xpine 0.0.30 → 0.0.32
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/index.js +276 -259
- package/dist/src/express.d.ts +1 -0
- package/dist/src/express.d.ts.map +1 -1
- package/dist/src/scripts/build.d.ts.map +1 -1
- package/dist/src/scripts/xpine-build.js +72 -35
- package/dist/src/scripts/xpine-dev.js +77 -40
- package/dist/src/util/regex.d.ts +2 -0
- package/dist/src/util/regex.d.ts.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/types.ts +2 -0
package/dist/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
// src/runDevServer.ts
|
|
2
2
|
import expressWs from "express-ws";
|
|
3
3
|
import http from "http";
|
|
4
|
-
import
|
|
5
|
-
import
|
|
4
|
+
import express2 from "express";
|
|
5
|
+
import EventEmitter2 from "events";
|
|
6
6
|
import chokidar from "chokidar";
|
|
7
7
|
|
|
8
8
|
// src/scripts/build.ts
|
|
9
|
-
import
|
|
10
|
-
import
|
|
9
|
+
import path6 from "path";
|
|
10
|
+
import fs6 from "fs-extra";
|
|
11
11
|
import { build } from "esbuild";
|
|
12
12
|
|
|
13
13
|
// src/build/typescript-builder.ts
|
|
@@ -285,7 +285,7 @@ async function triggerXPineOnLoad(noCache = false) {
|
|
|
285
285
|
}
|
|
286
286
|
|
|
287
287
|
// src/scripts/build.ts
|
|
288
|
-
import { globSync } from "glob";
|
|
288
|
+
import { globSync as globSync2 } from "glob";
|
|
289
289
|
import postcss from "postcss";
|
|
290
290
|
import tailwindPostcss from "@tailwindcss/postcss";
|
|
291
291
|
|
|
@@ -326,7 +326,9 @@ var regex_default = {
|
|
|
326
326
|
dynamicRoutes: /(\[)(.*?)(\])/g,
|
|
327
327
|
isDynamicRoute: /\[(.*)\]/g,
|
|
328
328
|
endsWithTSX: /\.tsx$/,
|
|
329
|
-
endsWithJSX: /\.jsx
|
|
329
|
+
endsWithJSX: /\.jsx$/,
|
|
330
|
+
endsWithFileName: /\.(html|tsx|jsx|js|ts)$/,
|
|
331
|
+
indexFile: /index\.(html|tsx|jsx|js|ts)$/g
|
|
330
332
|
};
|
|
331
333
|
|
|
332
334
|
// src/util/config-file.ts
|
|
@@ -449,8 +451,227 @@ var staticComment = "<!-- static -->";
|
|
|
449
451
|
|
|
450
452
|
// src/scripts/build.ts
|
|
451
453
|
import ts3 from "typescript";
|
|
454
|
+
|
|
455
|
+
// src/express.ts
|
|
456
|
+
import express from "express";
|
|
457
|
+
import { globSync } from "glob";
|
|
458
|
+
|
|
459
|
+
// src/auth.ts
|
|
460
|
+
import jsonwebtoken from "jsonwebtoken";
|
|
461
|
+
var { verify, sign } = jsonwebtoken;
|
|
462
|
+
async function signUser(email, username) {
|
|
463
|
+
return new Promise((resolve, reject) => {
|
|
464
|
+
sign(
|
|
465
|
+
{
|
|
466
|
+
user: {
|
|
467
|
+
email,
|
|
468
|
+
username
|
|
469
|
+
}
|
|
470
|
+
},
|
|
471
|
+
// @ts-ignore
|
|
472
|
+
process.env.JWT_PRIVATE_KEY,
|
|
473
|
+
{ expiresIn: "30d" },
|
|
474
|
+
(err, token) => {
|
|
475
|
+
if (err) reject(err);
|
|
476
|
+
resolve(token);
|
|
477
|
+
}
|
|
478
|
+
);
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
async function verifyUser(token) {
|
|
482
|
+
return new Promise((resolve, reject) => {
|
|
483
|
+
verify(token, process.env.JWT_PRIVATE_KEY, (err, authorizedData) => {
|
|
484
|
+
if (err) reject(err);
|
|
485
|
+
resolve(authorizedData);
|
|
486
|
+
});
|
|
487
|
+
});
|
|
488
|
+
}
|
|
489
|
+
function getTokenFromRequest(req) {
|
|
490
|
+
const { authorization } = req.headers;
|
|
491
|
+
if (!authorization) return null;
|
|
492
|
+
const token = authorization.split(" ").pop() || "";
|
|
493
|
+
return token || null;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
// src/express.ts
|
|
497
|
+
import requestIP from "request-ip";
|
|
498
|
+
import fs5 from "fs-extra";
|
|
499
|
+
import path5 from "path";
|
|
500
|
+
import EventEmitter from "events";
|
|
501
|
+
var OnInitEmitter = class extends EventEmitter {
|
|
502
|
+
};
|
|
503
|
+
var onInitEmitter = new OnInitEmitter();
|
|
504
|
+
onInitEmitter.on("triggerOnInit", async (paths) => {
|
|
505
|
+
for (const routePath of paths) {
|
|
506
|
+
const pathImport = await import(routePath.path + `?cache=${Date.now()}`);
|
|
507
|
+
if (pathImport?.config?.onInit) await pathImport.config.onInit();
|
|
508
|
+
}
|
|
509
|
+
});
|
|
510
|
+
function getAllBuiltRoutes() {
|
|
511
|
+
const routes = globSync(config.pagesDir + "/**/*.{tsx,ts}");
|
|
512
|
+
return routes.map((route) => {
|
|
513
|
+
const routeFormatted = route.split(config.pagesDir).pop().replace(".tsx", "").replace(".js", "").replace(".ts", "");
|
|
514
|
+
if (routeFormatted.endsWith("+config")) return;
|
|
515
|
+
const routeFormattedWithIndex = routeFormatted.replace(/\/index$/g, "");
|
|
516
|
+
return {
|
|
517
|
+
route: routeFormattedWithIndex,
|
|
518
|
+
path: route.replace(config.srcDir, config.distDir).replace(".tsx", ".js").replace(".ts", ".js"),
|
|
519
|
+
originalRoute: route
|
|
520
|
+
};
|
|
521
|
+
}).filter(Boolean);
|
|
522
|
+
}
|
|
523
|
+
async function createRouter() {
|
|
524
|
+
const isDev = process.env.NODE_ENV === "development";
|
|
525
|
+
const methods = ["get", "post", "put", "patch", "delete"];
|
|
526
|
+
const router = express.Router();
|
|
527
|
+
const routeMap = getAllBuiltRoutes();
|
|
528
|
+
const routeResults = [];
|
|
529
|
+
const configFiles = globSync(config.pagesDir + "/**/+config.{tsx,ts}");
|
|
530
|
+
await triggerXPineOnLoad();
|
|
531
|
+
for (const route of routeMap) {
|
|
532
|
+
const isJSX = route.originalRoute.endsWith(".tsx") || route.originalRoute.endsWith(".jsx");
|
|
533
|
+
const slugRoute = route.route.replace(/[ ]/g, "");
|
|
534
|
+
const foundMethod = methods.find((method) => slugRoute.endsWith(`.${method}`));
|
|
535
|
+
const isDynamicRoute = slugRoute.match(regex_default.isDynamicRoute);
|
|
536
|
+
let formattedRouteItem = slugRoute;
|
|
537
|
+
if (foundMethod) formattedRouteItem = formattedRouteItem.split(".").shift();
|
|
538
|
+
if (isDynamicRoute) {
|
|
539
|
+
const result = [...formattedRouteItem.matchAll(regex_default.dynamicRoutes)];
|
|
540
|
+
for (const match of result) {
|
|
541
|
+
formattedRouteItem = formattedRouteItem.replace(match[0], ":" + match[2]);
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
const componentImport = await import(route.path);
|
|
545
|
+
const componentFn = isDev ? null : componentImport?.default;
|
|
546
|
+
if (componentImport?.config?.onInit) {
|
|
547
|
+
await componentImport.config?.onInit();
|
|
548
|
+
}
|
|
549
|
+
let config2 = {};
|
|
550
|
+
const configFilePaths = getConfigFiles(route.originalRoute, configFiles);
|
|
551
|
+
if (!isDev) {
|
|
552
|
+
config2 = configFilePaths && await getCompleteConfig(configFilePaths, Date.now());
|
|
553
|
+
if (componentImport?.config) {
|
|
554
|
+
config2 = {
|
|
555
|
+
...config2,
|
|
556
|
+
...componentImport.config
|
|
557
|
+
};
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
routeResults.push({
|
|
561
|
+
formattedRouteItem,
|
|
562
|
+
foundMethod,
|
|
563
|
+
route
|
|
564
|
+
});
|
|
565
|
+
router[foundMethod || "get"](formattedRouteItem, async (req, res) => {
|
|
566
|
+
const urlPath = req?.route?.path || "/";
|
|
567
|
+
try {
|
|
568
|
+
const staticPath = routeHasStaticPath(formattedRouteItem, req.params);
|
|
569
|
+
if (staticPath && !isDev) {
|
|
570
|
+
res.sendFile(staticPath);
|
|
571
|
+
return;
|
|
572
|
+
}
|
|
573
|
+
if (componentFn && !isDev) {
|
|
574
|
+
if (isJSX) {
|
|
575
|
+
const data = config2?.data ? await config2.data(req) : null;
|
|
576
|
+
const originalResult = await componentFn({ req, res, data, routePath: urlPath });
|
|
577
|
+
const output = config2?.wrapper ? await config2.wrapper({ req, children: originalResult, config: config2, data, routePath: urlPath }) : originalResult;
|
|
578
|
+
res.send(doctypeHTML + output);
|
|
579
|
+
} else {
|
|
580
|
+
await componentFn(req, res);
|
|
581
|
+
}
|
|
582
|
+
return;
|
|
583
|
+
}
|
|
584
|
+
await triggerXPineOnLoad(true);
|
|
585
|
+
const componentImportDev = await import(route.path + `?cache=${Date.now()}`);
|
|
586
|
+
const componentFnDev = componentImportDev.default;
|
|
587
|
+
onInitEmitter.emit("triggerOnInit", getAllBuiltRoutes());
|
|
588
|
+
if (isJSX) {
|
|
589
|
+
let config3 = configFilePaths && await getCompleteConfig(configFilePaths, Date.now());
|
|
590
|
+
if (componentImportDev?.config) {
|
|
591
|
+
config3 = {
|
|
592
|
+
...config3,
|
|
593
|
+
...componentImportDev.config
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
const data = config3?.data ? await config3.data(req) : null;
|
|
597
|
+
const originalResult = await componentFnDev({ req, res, data, config: config3, routePath: urlPath });
|
|
598
|
+
const output = config3?.wrapper ? await config3.wrapper({ req, children: originalResult, config: config3, data, routePath: urlPath }) : originalResult;
|
|
599
|
+
context.clear();
|
|
600
|
+
res.send(doctypeHTML + output);
|
|
601
|
+
} else {
|
|
602
|
+
await componentFnDev(req, res);
|
|
603
|
+
}
|
|
604
|
+
} catch (err) {
|
|
605
|
+
console.error(err);
|
|
606
|
+
res.status(err?.status || 500).send(err?.message || "Error");
|
|
607
|
+
}
|
|
608
|
+
});
|
|
609
|
+
}
|
|
610
|
+
return {
|
|
611
|
+
router,
|
|
612
|
+
routeResults
|
|
613
|
+
};
|
|
614
|
+
}
|
|
615
|
+
async function verifyUserMiddleware(req, _res, next) {
|
|
616
|
+
const { usertoken } = req.cookies;
|
|
617
|
+
if (!usertoken) {
|
|
618
|
+
req.user = null;
|
|
619
|
+
}
|
|
620
|
+
try {
|
|
621
|
+
const { user } = await verifyUser(usertoken);
|
|
622
|
+
req.user = user;
|
|
623
|
+
} catch (err) {
|
|
624
|
+
req.user = null;
|
|
625
|
+
}
|
|
626
|
+
next();
|
|
627
|
+
}
|
|
628
|
+
async function createXPineRouter(app, beforeErrorRoute) {
|
|
629
|
+
app.use(express.static(config.distPublicDir));
|
|
630
|
+
app.use(verifyUserMiddleware);
|
|
631
|
+
app.use(requestIP.mw());
|
|
632
|
+
const { router, routeResults } = await createRouter();
|
|
633
|
+
app.use(function replaceableRouter(req, res, next) {
|
|
634
|
+
router(req, res, next);
|
|
635
|
+
});
|
|
636
|
+
const found404 = routeResults?.find((item) => item?.formattedRouteItem === "/404");
|
|
637
|
+
const import404 = process.env.NODE_ENV === "development" || !found404 ? null : (await import(found404.route.path)).default;
|
|
638
|
+
if (beforeErrorRoute) beforeErrorRoute(app);
|
|
639
|
+
app.use(async function(req, res) {
|
|
640
|
+
res.status(404);
|
|
641
|
+
if (import404) {
|
|
642
|
+
res.send(doctypeHTML + await import404(req, res));
|
|
643
|
+
} else if (found404 && process.env.NODE_ENV === "development") {
|
|
644
|
+
const import404Item = (await import(found404.route.path + `?cache=${Date.now()}`)).default;
|
|
645
|
+
res.send(doctypeHTML + await import404Item(req, res));
|
|
646
|
+
} else {
|
|
647
|
+
res.send("Error");
|
|
648
|
+
}
|
|
649
|
+
});
|
|
650
|
+
}
|
|
651
|
+
function routeHasStaticPath(route, params) {
|
|
652
|
+
const paramEntries = Object.entries(params);
|
|
653
|
+
let routeToStaticPath = route;
|
|
654
|
+
for (const [key, value] of paramEntries) {
|
|
655
|
+
routeToStaticPath = routeToStaticPath.replace(`:${key}`, value);
|
|
656
|
+
}
|
|
657
|
+
routeToStaticPath += "/index.html";
|
|
658
|
+
const outputPath = path5.join(config.distPagesDir, routeToStaticPath);
|
|
659
|
+
if (fs5.existsSync(outputPath)) return outputPath;
|
|
660
|
+
return false;
|
|
661
|
+
}
|
|
662
|
+
function filePathToURLPath(pathName, isDist = true) {
|
|
663
|
+
const result = pathName.split(isDist ? config.distPagesDir : config.pagesDir).pop().replace(regex_default.indexFile, "").replace(regex_default.endsWithFileName, "");
|
|
664
|
+
if (result.endsWith("/")) {
|
|
665
|
+
const cleanedResult = result.slice(0, -1);
|
|
666
|
+
if (!cleanedResult) return "/";
|
|
667
|
+
return cleanedResult;
|
|
668
|
+
}
|
|
669
|
+
return result;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
// src/scripts/build.ts
|
|
452
673
|
var extensions = [".ts", ".tsx"];
|
|
453
|
-
var packageJson = JSON.parse(
|
|
674
|
+
var packageJson = JSON.parse(fs6.readFileSync(config.packageJsonPath, "utf-8"));
|
|
454
675
|
var allPackages = Object.keys(packageJson.devDependencies).concat(Object.keys(packageJson.dependencies));
|
|
455
676
|
var xpineDistDir = getXPineDistDir();
|
|
456
677
|
async function buildApp(args) {
|
|
@@ -458,12 +679,12 @@ async function buildApp(args) {
|
|
|
458
679
|
const removePreviousBuild = args?.removePreviousBuild || false;
|
|
459
680
|
const disableTailwind = args?.disableTailwind || false;
|
|
460
681
|
try {
|
|
461
|
-
if (removePreviousBuild)
|
|
462
|
-
const srcDirFiles =
|
|
682
|
+
if (removePreviousBuild) fs6.removeSync(config.distDir);
|
|
683
|
+
const srcDirFiles = globSync2(config.srcDir + "/**/*.{js,ts,tsx,jsx}");
|
|
463
684
|
const { componentData, dataFiles } = await buildAppFiles(srcDirFiles, isDev);
|
|
464
685
|
const alpineDataFile = await buildAlpineDataFile(componentData, dataFiles);
|
|
465
686
|
await buildClientSideFiles([alpineDataFile], isDev);
|
|
466
|
-
|
|
687
|
+
fs6.removeSync(config.distTempFolder);
|
|
467
688
|
await buildCSS(disableTailwind);
|
|
468
689
|
await buildPublicFolderSymlinks();
|
|
469
690
|
await buildOnLoadFile(componentData, isDev);
|
|
@@ -483,7 +704,7 @@ async function buildAppFiles(files, isDev) {
|
|
|
483
704
|
return fileName === "+config";
|
|
484
705
|
});
|
|
485
706
|
const backendFiles = files.filter((file) => extensions.find((ext) => file.endsWith(ext))).filter((file) => !file.startsWith(config.publicDir));
|
|
486
|
-
|
|
707
|
+
fs6.ensureDirSync(config.distDir);
|
|
487
708
|
await build({
|
|
488
709
|
entryPoints: backendFiles,
|
|
489
710
|
format: "esm",
|
|
@@ -507,10 +728,10 @@ async function buildAppFiles(files, isDev) {
|
|
|
507
728
|
};
|
|
508
729
|
}
|
|
509
730
|
async function buildClientSideFiles(alpineDataFiles = [], isDev) {
|
|
510
|
-
const tempFilePath =
|
|
511
|
-
|
|
731
|
+
const tempFilePath = path6.join(config.distTempFolder, "./app.ts");
|
|
732
|
+
fs6.ensureFileSync(tempFilePath);
|
|
512
733
|
const pagesScriptsGlob = config.publicDir + "/scripts/pages/**/*.{js,ts}";
|
|
513
|
-
const clientFiles =
|
|
734
|
+
const clientFiles = globSync2(
|
|
514
735
|
config.publicDir + "/**/*.{js,ts}",
|
|
515
736
|
{
|
|
516
737
|
ignore: pagesScriptsGlob
|
|
@@ -526,7 +747,7 @@ async function buildClientSideFiles(alpineDataFiles = [], isDev) {
|
|
|
526
747
|
minify: !isDev,
|
|
527
748
|
sourcemap: isDev ? "inline" : false
|
|
528
749
|
});
|
|
529
|
-
const pagesFiles =
|
|
750
|
+
const pagesFiles = globSync2(pagesScriptsGlob);
|
|
530
751
|
await build({
|
|
531
752
|
entryPoints: pagesFiles || [],
|
|
532
753
|
bundle: true,
|
|
@@ -537,14 +758,14 @@ async function buildClientSideFiles(alpineDataFiles = [], isDev) {
|
|
|
537
758
|
await logSize(config.distPublicDir, "client");
|
|
538
759
|
}
|
|
539
760
|
function writeDevServerClientSideCode(tempFilePath) {
|
|
540
|
-
const devServerPath =
|
|
541
|
-
const content =
|
|
542
|
-
|
|
761
|
+
const devServerPath = path6.join(xpineDistDir, "./src/static/dev-server.js");
|
|
762
|
+
const content = fs6.readFileSync(devServerPath, "utf-8");
|
|
763
|
+
fs6.appendFileSync(tempFilePath, "\n" + content);
|
|
543
764
|
}
|
|
544
765
|
function writeSpaClientSideCode(tempFilePath) {
|
|
545
|
-
const spaPath =
|
|
546
|
-
const content =
|
|
547
|
-
|
|
766
|
+
const spaPath = path6.join(xpineDistDir, "./src/static/spa.js");
|
|
767
|
+
const content = fs6.readFileSync(spaPath, "utf-8");
|
|
768
|
+
fs6.appendFileSync(tempFilePath, "\n" + content);
|
|
548
769
|
}
|
|
549
770
|
async function buildAlpineDataFile(componentData, dataFiles) {
|
|
550
771
|
const output = {
|
|
@@ -590,23 +811,23 @@ async function buildAlpineDataFile(componentData, dataFiles) {
|
|
|
590
811
|
output.code.push(`Alpine.data('${dataFunction.name}', ${dataFunction.name});`);
|
|
591
812
|
}
|
|
592
813
|
const result = output.imports.join("\n") + "\n" + output.code.join("\n") + "\n" + output.end.join("\n");
|
|
593
|
-
|
|
594
|
-
|
|
814
|
+
fs6.ensureFileSync(config.alpineDataPath);
|
|
815
|
+
fs6.writeFileSync(config.alpineDataPath, result);
|
|
595
816
|
return config.alpineDataPath;
|
|
596
817
|
}
|
|
597
818
|
async function buildCSS(disableTailwind) {
|
|
598
|
-
const cssFiles =
|
|
819
|
+
const cssFiles = globSync2(config.srcDir + "/**/*.css");
|
|
599
820
|
for (const file of cssFiles) {
|
|
600
|
-
const fileContents =
|
|
821
|
+
const fileContents = fs6.readFileSync(file, "utf-8");
|
|
601
822
|
const result = disableTailwind ? fileContents : await postcss([tailwindPostcss(), remove_layers_default()]).process(fileContents, { from: file });
|
|
602
823
|
const newPath = file.replace(config.srcDir, config.distDir);
|
|
603
|
-
|
|
604
|
-
|
|
824
|
+
fs6.ensureFileSync(newPath);
|
|
825
|
+
fs6.writeFileSync(newPath, result.css);
|
|
605
826
|
}
|
|
606
827
|
logSize(config.distPublicDir, "css");
|
|
607
828
|
}
|
|
608
829
|
async function buildPublicFolderSymlinks() {
|
|
609
|
-
const files =
|
|
830
|
+
const files = globSync2(config.publicDir + "/**/*.*", {
|
|
610
831
|
ignore: "/**/*.{css,js,ts,tsx,jsx}"
|
|
611
832
|
});
|
|
612
833
|
for (const file of files) {
|
|
@@ -615,19 +836,19 @@ async function buildPublicFolderSymlinks() {
|
|
|
615
836
|
const splitNewPath = newPath.split("/");
|
|
616
837
|
splitNewPath.pop();
|
|
617
838
|
const newDir = splitNewPath.join("/");
|
|
618
|
-
|
|
619
|
-
|
|
839
|
+
fs6.ensureDirSync(newDir);
|
|
840
|
+
fs6.symlinkSync(file, newPath);
|
|
620
841
|
} catch {
|
|
621
842
|
}
|
|
622
843
|
}
|
|
623
844
|
}
|
|
624
845
|
async function logSize(pathName, type, validExtensions = [".js", ".css"]) {
|
|
625
|
-
const files =
|
|
846
|
+
const files = globSync2(pathName + "/**/*" + (type === "css" ? ".css" : ""));
|
|
626
847
|
const fileSizes = files.map((file) => {
|
|
627
848
|
if (!validExtensions.find((ext) => file.endsWith(ext))) return false;
|
|
628
849
|
return {
|
|
629
850
|
file,
|
|
630
|
-
size:
|
|
851
|
+
size: fs6.statSync(file).size / (1024 * 1e3)
|
|
631
852
|
};
|
|
632
853
|
}).filter(Boolean);
|
|
633
854
|
const totalSize = fileSizes.reduce((total, current) => {
|
|
@@ -663,15 +884,16 @@ async function buildStaticFiles(config2, component, componentImport, builtCompon
|
|
|
663
884
|
if (componentImport?.onInit) await componentImport.onInit();
|
|
664
885
|
const outputPath = componentDynamicPaths?.length ? componentDynamicPaths.reduce((total, current) => {
|
|
665
886
|
return total.replace(`/[${current}]`, "");
|
|
666
|
-
},
|
|
887
|
+
}, path6.dirname(builtComponentPath)) : path6.dirname(builtComponentPath);
|
|
667
888
|
if (typeof config2?.staticPaths === "boolean") {
|
|
889
|
+
const urlPath = filePathToURLPath(outputPath);
|
|
668
890
|
try {
|
|
669
891
|
const req = { params: {} };
|
|
670
892
|
const data = config2?.data ? await config2.data(req) : null;
|
|
671
|
-
const staticComponentOutput = await componentFn({ data });
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
doctypeHTML + (config2?.wrapper ? await config2.wrapper({ req, children: staticComponentOutput, config: config2, data }) : staticComponentOutput) + staticComment
|
|
893
|
+
const staticComponentOutput = await componentFn({ data, routePath: urlPath });
|
|
894
|
+
fs6.writeFileSync(
|
|
895
|
+
path6.join(outputPath, "./index.html"),
|
|
896
|
+
doctypeHTML + (config2?.wrapper ? await config2.wrapper({ req, children: staticComponentOutput, config: config2, data, routePath: urlPath }) : staticComponentOutput) + staticComment
|
|
675
897
|
);
|
|
676
898
|
} catch (err) {
|
|
677
899
|
console.error(err);
|
|
@@ -686,13 +908,14 @@ async function buildStaticFiles(config2, component, componentImport, builtCompon
|
|
|
686
908
|
...componentDynamicPaths?.length ? dynamicPath : {}
|
|
687
909
|
}
|
|
688
910
|
};
|
|
911
|
+
const updatedOutDir = path6.join(outputPath, `./${componentDynamicPaths.map((key) => dynamicPath[key]).join("/")}`);
|
|
912
|
+
const urlPath = filePathToURLPath(updatedOutDir);
|
|
689
913
|
const data = config2?.data ? await config2.data(req) : null;
|
|
690
|
-
const staticComponentOutput = await componentFn({ req, data });
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
doctypeHTML + (config2?.wrapper ? await config2.wrapper({ req, children: staticComponentOutput, config: config2, data }) : staticComponentOutput) + staticComment
|
|
914
|
+
const staticComponentOutput = await componentFn({ req, data, routePath: urlPath });
|
|
915
|
+
fs6.ensureDirSync(updatedOutDir);
|
|
916
|
+
fs6.writeFileSync(
|
|
917
|
+
path6.join(updatedOutDir, "./index.html"),
|
|
918
|
+
doctypeHTML + (config2?.wrapper ? await config2.wrapper({ req, children: staticComponentOutput, config: config2, data, routePath: urlPath }) : staticComponentOutput) + staticComment
|
|
696
919
|
);
|
|
697
920
|
} catch (err) {
|
|
698
921
|
console.log("Could not build static component", component.path);
|
|
@@ -740,8 +963,8 @@ async function buildOnLoadFile(componentData, isDev) {
|
|
|
740
963
|
context.runArrayQueue();
|
|
741
964
|
}
|
|
742
965
|
`;
|
|
743
|
-
const onLoadFilePath =
|
|
744
|
-
|
|
966
|
+
const onLoadFilePath = path6.join(config.distDir, "./__xpineOnLoad.ts");
|
|
967
|
+
fs6.writeFileSync(onLoadFilePath, output);
|
|
745
968
|
await build({
|
|
746
969
|
entryPoints: [onLoadFilePath],
|
|
747
970
|
format: "esm",
|
|
@@ -759,15 +982,15 @@ async function buildOnLoadFile(componentData, isDev) {
|
|
|
759
982
|
}
|
|
760
983
|
|
|
761
984
|
// src/runDevServer.ts
|
|
762
|
-
import
|
|
985
|
+
import path8 from "path";
|
|
763
986
|
|
|
764
987
|
// src/util/env.ts
|
|
765
988
|
import dotenv from "dotenv";
|
|
766
|
-
import
|
|
989
|
+
import path7 from "path";
|
|
767
990
|
import { GetSecretValueCommand, SecretsManagerClient } from "@aws-sdk/client-secrets-manager";
|
|
768
991
|
async function setupEnv() {
|
|
769
992
|
if (process.env.HAS_SETUP_ENV) return;
|
|
770
|
-
dotenv.config({ path:
|
|
993
|
+
dotenv.config({ path: path7.join(config.rootDir, `./.env.${process.env.STAGE || "dev"}`) });
|
|
771
994
|
await loadSecretsManagerSecrets();
|
|
772
995
|
process.env.HAS_SETUP_ENV = "true";
|
|
773
996
|
}
|
|
@@ -803,7 +1026,7 @@ async function runDevServer() {
|
|
|
803
1026
|
const watcher = chokidar.watch(config.srcDir, {
|
|
804
1027
|
ignoreInitial: true,
|
|
805
1028
|
// Ignore map and prisma files
|
|
806
|
-
ignored: (pathName) => pathName.endsWith(".map") || pathName.startsWith(
|
|
1029
|
+
ignored: (pathName) => pathName.endsWith(".map") || pathName.startsWith(path8.join(config.serverDir, "./prisma"))
|
|
807
1030
|
});
|
|
808
1031
|
watcher.on("all", async (event, path9) => {
|
|
809
1032
|
const shouldReloadServer = path9.startsWith(config.serverDir) && !path9.startsWith(config.runDir) || ["add", "unlink"].includes(event) && path9.startsWith(config.pagesDir);
|
|
@@ -823,10 +1046,10 @@ async function runDevServer() {
|
|
|
823
1046
|
const startServer2 = (await import(config.serverDistAppPath + `?cache=${Date.now()}`)).default;
|
|
824
1047
|
appServer = await startServer2();
|
|
825
1048
|
}
|
|
826
|
-
const wsApp =
|
|
1049
|
+
const wsApp = express2();
|
|
827
1050
|
const wsServer = http.createServer(wsApp);
|
|
828
1051
|
expressWs(wsApp, wsServer);
|
|
829
|
-
class RefreshEmitter extends
|
|
1052
|
+
class RefreshEmitter extends EventEmitter2 {
|
|
830
1053
|
}
|
|
831
1054
|
;
|
|
832
1055
|
const refreshEmitter = new RefreshEmitter();
|
|
@@ -849,7 +1072,7 @@ function asyncServerClose(server) {
|
|
|
849
1072
|
});
|
|
850
1073
|
}
|
|
851
1074
|
function createRebuildEmitter(delay = 500) {
|
|
852
|
-
class RebuildEmitter extends
|
|
1075
|
+
class RebuildEmitter extends EventEmitter2 {
|
|
853
1076
|
}
|
|
854
1077
|
;
|
|
855
1078
|
const rebuildEmitter = new RebuildEmitter();
|
|
@@ -874,213 +1097,6 @@ function createRebuildEmitter(delay = 500) {
|
|
|
874
1097
|
return rebuildEmitter;
|
|
875
1098
|
}
|
|
876
1099
|
|
|
877
|
-
// src/express.ts
|
|
878
|
-
import express2 from "express";
|
|
879
|
-
import { globSync as globSync2 } from "glob";
|
|
880
|
-
|
|
881
|
-
// src/auth.ts
|
|
882
|
-
import jsonwebtoken from "jsonwebtoken";
|
|
883
|
-
var { verify, sign } = jsonwebtoken;
|
|
884
|
-
async function signUser(email, username) {
|
|
885
|
-
return new Promise((resolve, reject) => {
|
|
886
|
-
sign(
|
|
887
|
-
{
|
|
888
|
-
user: {
|
|
889
|
-
email,
|
|
890
|
-
username
|
|
891
|
-
}
|
|
892
|
-
},
|
|
893
|
-
// @ts-ignore
|
|
894
|
-
process.env.JWT_PRIVATE_KEY,
|
|
895
|
-
{ expiresIn: "30d" },
|
|
896
|
-
(err, token) => {
|
|
897
|
-
if (err) reject(err);
|
|
898
|
-
resolve(token);
|
|
899
|
-
}
|
|
900
|
-
);
|
|
901
|
-
});
|
|
902
|
-
}
|
|
903
|
-
async function verifyUser(token) {
|
|
904
|
-
return new Promise((resolve, reject) => {
|
|
905
|
-
verify(token, process.env.JWT_PRIVATE_KEY, (err, authorizedData) => {
|
|
906
|
-
if (err) reject(err);
|
|
907
|
-
resolve(authorizedData);
|
|
908
|
-
});
|
|
909
|
-
});
|
|
910
|
-
}
|
|
911
|
-
function getTokenFromRequest(req) {
|
|
912
|
-
const { authorization } = req.headers;
|
|
913
|
-
if (!authorization) return null;
|
|
914
|
-
const token = authorization.split(" ").pop() || "";
|
|
915
|
-
return token || null;
|
|
916
|
-
}
|
|
917
|
-
|
|
918
|
-
// src/express.ts
|
|
919
|
-
import requestIP from "request-ip";
|
|
920
|
-
import fs6 from "fs-extra";
|
|
921
|
-
import path8 from "path";
|
|
922
|
-
import EventEmitter2 from "events";
|
|
923
|
-
var OnInitEmitter = class extends EventEmitter2 {
|
|
924
|
-
};
|
|
925
|
-
var onInitEmitter = new OnInitEmitter();
|
|
926
|
-
onInitEmitter.on("triggerOnInit", async (paths) => {
|
|
927
|
-
for (const routePath of paths) {
|
|
928
|
-
const pathImport = await import(routePath.path + `?cache=${Date.now()}`);
|
|
929
|
-
if (pathImport?.config?.onInit) await pathImport.config.onInit();
|
|
930
|
-
}
|
|
931
|
-
});
|
|
932
|
-
function getAllBuiltRoutes() {
|
|
933
|
-
const routes = globSync2(config.pagesDir + "/**/*.{tsx,ts}");
|
|
934
|
-
return routes.map((route) => {
|
|
935
|
-
const routeFormatted = route.split(config.pagesDir).pop().replace(".tsx", "").replace(".js", "").replace(".ts", "");
|
|
936
|
-
if (routeFormatted.endsWith("+config")) return;
|
|
937
|
-
const routeFormattedWithIndex = routeFormatted.replace(/\/index$/g, "");
|
|
938
|
-
return {
|
|
939
|
-
route: routeFormattedWithIndex,
|
|
940
|
-
path: route.replace(config.srcDir, config.distDir).replace(".tsx", ".js").replace(".ts", ".js"),
|
|
941
|
-
originalRoute: route
|
|
942
|
-
};
|
|
943
|
-
}).filter(Boolean);
|
|
944
|
-
}
|
|
945
|
-
async function createRouter() {
|
|
946
|
-
const isDev = process.env.NODE_ENV === "development";
|
|
947
|
-
const methods = ["get", "post", "put", "patch", "delete"];
|
|
948
|
-
const router = express2.Router();
|
|
949
|
-
const routeMap = getAllBuiltRoutes();
|
|
950
|
-
const routeResults = [];
|
|
951
|
-
const configFiles = globSync2(config.pagesDir + "/**/+config.{tsx,ts}");
|
|
952
|
-
await triggerXPineOnLoad();
|
|
953
|
-
for (const route of routeMap) {
|
|
954
|
-
const isJSX = route.originalRoute.endsWith(".tsx") || route.originalRoute.endsWith(".jsx");
|
|
955
|
-
const slugRoute = route.route.replace(/[ ]/g, "");
|
|
956
|
-
const foundMethod = methods.find((method) => slugRoute.endsWith(`.${method}`));
|
|
957
|
-
const isDynamicRoute = slugRoute.match(regex_default.isDynamicRoute);
|
|
958
|
-
let formattedRouteItem = slugRoute;
|
|
959
|
-
if (foundMethod) formattedRouteItem = formattedRouteItem.split(".").shift();
|
|
960
|
-
if (isDynamicRoute) {
|
|
961
|
-
const result = [...formattedRouteItem.matchAll(regex_default.dynamicRoutes)];
|
|
962
|
-
for (const match of result) {
|
|
963
|
-
formattedRouteItem = formattedRouteItem.replace(match[0], ":" + match[2]);
|
|
964
|
-
}
|
|
965
|
-
}
|
|
966
|
-
const componentImport = await import(route.path);
|
|
967
|
-
const componentFn = isDev ? null : componentImport?.default;
|
|
968
|
-
if (componentImport?.config?.onInit) {
|
|
969
|
-
await componentImport.config?.onInit();
|
|
970
|
-
}
|
|
971
|
-
let config2 = {};
|
|
972
|
-
const configFilePaths = getConfigFiles(route.originalRoute, configFiles);
|
|
973
|
-
if (!isDev) {
|
|
974
|
-
config2 = configFilePaths && await getCompleteConfig(configFilePaths, Date.now());
|
|
975
|
-
if (componentImport?.config) {
|
|
976
|
-
config2 = {
|
|
977
|
-
...config2,
|
|
978
|
-
...componentImport.config
|
|
979
|
-
};
|
|
980
|
-
}
|
|
981
|
-
}
|
|
982
|
-
routeResults.push({
|
|
983
|
-
formattedRouteItem,
|
|
984
|
-
foundMethod,
|
|
985
|
-
route
|
|
986
|
-
});
|
|
987
|
-
router[foundMethod || "get"](formattedRouteItem, async (req, res) => {
|
|
988
|
-
try {
|
|
989
|
-
const staticPath = routeHasStaticPath(formattedRouteItem, req.params);
|
|
990
|
-
if (staticPath && !isDev) {
|
|
991
|
-
res.sendFile(staticPath);
|
|
992
|
-
return;
|
|
993
|
-
}
|
|
994
|
-
if (componentFn && !isDev) {
|
|
995
|
-
if (isJSX) {
|
|
996
|
-
const data = config2?.data ? await config2.data(req) : null;
|
|
997
|
-
const originalResult = await componentFn({ req, res, data });
|
|
998
|
-
const output = config2?.wrapper ? await config2.wrapper({ req, children: originalResult, config: config2, data }) : originalResult;
|
|
999
|
-
res.send(doctypeHTML + output);
|
|
1000
|
-
} else {
|
|
1001
|
-
await componentFn(req, res);
|
|
1002
|
-
}
|
|
1003
|
-
return;
|
|
1004
|
-
}
|
|
1005
|
-
await triggerXPineOnLoad(true);
|
|
1006
|
-
const componentImportDev = await import(route.path + `?cache=${Date.now()}`);
|
|
1007
|
-
const componentFnDev = componentImportDev.default;
|
|
1008
|
-
onInitEmitter.emit("triggerOnInit", getAllBuiltRoutes());
|
|
1009
|
-
if (isJSX) {
|
|
1010
|
-
let config3 = configFilePaths && await getCompleteConfig(configFilePaths, Date.now());
|
|
1011
|
-
if (componentImportDev?.config) {
|
|
1012
|
-
config3 = {
|
|
1013
|
-
...config3,
|
|
1014
|
-
...componentImportDev.config
|
|
1015
|
-
};
|
|
1016
|
-
}
|
|
1017
|
-
const data = config3?.data ? await config3.data(req) : null;
|
|
1018
|
-
const originalResult = await componentFnDev({ req, res, data, config: config3 });
|
|
1019
|
-
const output = config3?.wrapper ? await config3.wrapper({ req, children: originalResult, config: config3, data }) : originalResult;
|
|
1020
|
-
context.clear();
|
|
1021
|
-
res.send(doctypeHTML + output);
|
|
1022
|
-
} else {
|
|
1023
|
-
await componentFnDev(req, res);
|
|
1024
|
-
}
|
|
1025
|
-
} catch (err) {
|
|
1026
|
-
console.error(err);
|
|
1027
|
-
res.status(err?.status || 500).send(err?.message || "Error");
|
|
1028
|
-
}
|
|
1029
|
-
});
|
|
1030
|
-
}
|
|
1031
|
-
return {
|
|
1032
|
-
router,
|
|
1033
|
-
routeResults
|
|
1034
|
-
};
|
|
1035
|
-
}
|
|
1036
|
-
async function verifyUserMiddleware(req, _res, next) {
|
|
1037
|
-
const { usertoken } = req.cookies;
|
|
1038
|
-
if (!usertoken) {
|
|
1039
|
-
req.user = null;
|
|
1040
|
-
}
|
|
1041
|
-
try {
|
|
1042
|
-
const { user } = await verifyUser(usertoken);
|
|
1043
|
-
req.user = user;
|
|
1044
|
-
} catch (err) {
|
|
1045
|
-
req.user = null;
|
|
1046
|
-
}
|
|
1047
|
-
next();
|
|
1048
|
-
}
|
|
1049
|
-
async function createXPineRouter(app, beforeErrorRoute) {
|
|
1050
|
-
app.use(express2.static(config.distPublicDir));
|
|
1051
|
-
app.use(verifyUserMiddleware);
|
|
1052
|
-
app.use(requestIP.mw());
|
|
1053
|
-
const { router, routeResults } = await createRouter();
|
|
1054
|
-
app.use(function replaceableRouter(req, res, next) {
|
|
1055
|
-
router(req, res, next);
|
|
1056
|
-
});
|
|
1057
|
-
const found404 = routeResults?.find((item) => item?.formattedRouteItem === "/404");
|
|
1058
|
-
const import404 = process.env.NODE_ENV === "development" || !found404 ? null : (await import(found404.route.path)).default;
|
|
1059
|
-
if (beforeErrorRoute) beforeErrorRoute(app);
|
|
1060
|
-
app.use(async function(req, res) {
|
|
1061
|
-
res.status(404);
|
|
1062
|
-
if (import404) {
|
|
1063
|
-
res.send(doctypeHTML + await import404(req, res));
|
|
1064
|
-
} else if (found404 && process.env.NODE_ENV === "development") {
|
|
1065
|
-
const import404Item = (await import(found404.route.path + `?cache=${Date.now()}`)).default;
|
|
1066
|
-
res.send(doctypeHTML + await import404Item(req, res));
|
|
1067
|
-
} else {
|
|
1068
|
-
res.send("Error");
|
|
1069
|
-
}
|
|
1070
|
-
});
|
|
1071
|
-
}
|
|
1072
|
-
function routeHasStaticPath(route, params) {
|
|
1073
|
-
const paramEntries = Object.entries(params);
|
|
1074
|
-
let routeToStaticPath = route;
|
|
1075
|
-
for (const [key, value] of paramEntries) {
|
|
1076
|
-
routeToStaticPath = routeToStaticPath.replace(`:${key}`, value);
|
|
1077
|
-
}
|
|
1078
|
-
routeToStaticPath += "/index.html";
|
|
1079
|
-
const outputPath = path8.join(config.distPagesDir, routeToStaticPath);
|
|
1080
|
-
if (fs6.existsSync(outputPath)) return outputPath;
|
|
1081
|
-
return false;
|
|
1082
|
-
}
|
|
1083
|
-
|
|
1084
1100
|
// src/util/html.ts
|
|
1085
1101
|
var html = class {
|
|
1086
1102
|
static attributeObjectToString(props) {
|
|
@@ -1120,6 +1136,7 @@ export {
|
|
|
1120
1136
|
createContext,
|
|
1121
1137
|
createRouter,
|
|
1122
1138
|
createXPineRouter,
|
|
1139
|
+
filePathToURLPath,
|
|
1123
1140
|
fromRoot,
|
|
1124
1141
|
getComponentDynamicPaths,
|
|
1125
1142
|
getTokenFromRequest,
|
package/dist/src/express.d.ts
CHANGED
|
@@ -7,4 +7,5 @@ export declare function createXPineRouter(app: any, beforeErrorRoute?: (app: Exp
|
|
|
7
7
|
export declare function routeHasStaticPath(route: string, params: {
|
|
8
8
|
[key: string]: string;
|
|
9
9
|
}): string | false;
|
|
10
|
+
export declare function filePathToURLPath(pathName: string, isDist?: boolean): string;
|
|
10
11
|
//# sourceMappingURL=express.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"express.d.ts","sourceRoot":"","sources":["../../src/express.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAgB,OAAO,EAAqB,MAAM,SAAS,CAAC;AAyC5E,wBAAsB,YAAY;;;
|
|
1
|
+
{"version":3,"file":"express.d.ts","sourceRoot":"","sources":["../../src/express.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAgB,OAAO,EAAqB,MAAM,SAAS,CAAC;AAyC5E,wBAAsB,YAAY;;;GA+GjC;AAiBD,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,iBA6B1F;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,GAAG,MAAM,GAAG,KAAK,CAWnG;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAE,OAAc,UAQzE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/scripts/build.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,UAAU,EAA2B,aAAa,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../../src/scripts/build.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,UAAU,EAA2B,aAAa,EAAE,MAAM,aAAa,CAAC;AAYjF,KAAK,YAAY,GAAG;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAA;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,YAAY,iBAsBhD;AA8ID,wBAAsB,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,iBAavD;AAGD,wBAAsB,yBAAyB,kBAgB9C;AAED,wBAAsB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,GAAG,QAAQ,GAAG,KAAK,EAAE,eAAe,WAAkB,iBAahH;AAED,wBAAsB,qBAAqB,CAAC,aAAa,EAAE,aAAa,EAAE,iBAezE;AAED,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,eAAe,EAAE,GAAG,EAAE,kBAAkB,EAAE,MAAM,iBAmEpI;AAED,wBAAgB,wBAAwB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,EAAE,CAQxE;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;CACZ,CAAA;AAGD,wBAAsB,eAAe,CAAC,aAAa,EAAE,aAAa,EAAE,EAAE,KAAK,CAAC,EAAE,OAAO,iBAoDpF"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
// src/scripts/build.ts
|
|
4
4
|
import path5 from "path";
|
|
5
|
-
import
|
|
5
|
+
import fs6 from "fs-extra";
|
|
6
6
|
import { build } from "esbuild";
|
|
7
7
|
|
|
8
8
|
// src/build/typescript-builder.ts
|
|
@@ -280,7 +280,7 @@ async function triggerXPineOnLoad(noCache = false) {
|
|
|
280
280
|
}
|
|
281
281
|
|
|
282
282
|
// src/scripts/build.ts
|
|
283
|
-
import { globSync } from "glob";
|
|
283
|
+
import { globSync as globSync2 } from "glob";
|
|
284
284
|
import postcss from "postcss";
|
|
285
285
|
import tailwindPostcss from "@tailwindcss/postcss";
|
|
286
286
|
|
|
@@ -321,7 +321,9 @@ var regex_default = {
|
|
|
321
321
|
dynamicRoutes: /(\[)(.*?)(\])/g,
|
|
322
322
|
isDynamicRoute: /\[(.*)\]/g,
|
|
323
323
|
endsWithTSX: /\.tsx$/,
|
|
324
|
-
endsWithJSX: /\.jsx
|
|
324
|
+
endsWithJSX: /\.jsx$/,
|
|
325
|
+
endsWithFileName: /\.(html|tsx|jsx|js|ts)$/,
|
|
326
|
+
indexFile: /index\.(html|tsx|jsx|js|ts)$/g
|
|
325
327
|
};
|
|
326
328
|
|
|
327
329
|
// src/util/config-file.ts
|
|
@@ -444,8 +446,41 @@ var staticComment = "<!-- static -->";
|
|
|
444
446
|
|
|
445
447
|
// src/scripts/build.ts
|
|
446
448
|
import ts3 from "typescript";
|
|
449
|
+
|
|
450
|
+
// src/express.ts
|
|
451
|
+
import express from "express";
|
|
452
|
+
import { globSync } from "glob";
|
|
453
|
+
|
|
454
|
+
// src/auth.ts
|
|
455
|
+
import jsonwebtoken from "jsonwebtoken";
|
|
456
|
+
var { verify, sign } = jsonwebtoken;
|
|
457
|
+
|
|
458
|
+
// src/express.ts
|
|
459
|
+
import requestIP from "request-ip";
|
|
460
|
+
import fs5 from "fs-extra";
|
|
461
|
+
import EventEmitter from "events";
|
|
462
|
+
var OnInitEmitter = class extends EventEmitter {
|
|
463
|
+
};
|
|
464
|
+
var onInitEmitter = new OnInitEmitter();
|
|
465
|
+
onInitEmitter.on("triggerOnInit", async (paths) => {
|
|
466
|
+
for (const routePath of paths) {
|
|
467
|
+
const pathImport = await import(routePath.path + `?cache=${Date.now()}`);
|
|
468
|
+
if (pathImport?.config?.onInit) await pathImport.config.onInit();
|
|
469
|
+
}
|
|
470
|
+
});
|
|
471
|
+
function filePathToURLPath(pathName, isDist = true) {
|
|
472
|
+
const result = pathName.split(isDist ? config.distPagesDir : config.pagesDir).pop().replace(regex_default.indexFile, "").replace(regex_default.endsWithFileName, "");
|
|
473
|
+
if (result.endsWith("/")) {
|
|
474
|
+
const cleanedResult = result.slice(0, -1);
|
|
475
|
+
if (!cleanedResult) return "/";
|
|
476
|
+
return cleanedResult;
|
|
477
|
+
}
|
|
478
|
+
return result;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
// src/scripts/build.ts
|
|
447
482
|
var extensions = [".ts", ".tsx"];
|
|
448
|
-
var packageJson = JSON.parse(
|
|
483
|
+
var packageJson = JSON.parse(fs6.readFileSync(config.packageJsonPath, "utf-8"));
|
|
449
484
|
var allPackages = Object.keys(packageJson.devDependencies).concat(Object.keys(packageJson.dependencies));
|
|
450
485
|
var xpineDistDir = getXPineDistDir();
|
|
451
486
|
async function buildApp(args) {
|
|
@@ -453,12 +488,12 @@ async function buildApp(args) {
|
|
|
453
488
|
const removePreviousBuild2 = args?.removePreviousBuild || false;
|
|
454
489
|
const disableTailwind2 = args?.disableTailwind || false;
|
|
455
490
|
try {
|
|
456
|
-
if (removePreviousBuild2)
|
|
457
|
-
const srcDirFiles =
|
|
491
|
+
if (removePreviousBuild2) fs6.removeSync(config.distDir);
|
|
492
|
+
const srcDirFiles = globSync2(config.srcDir + "/**/*.{js,ts,tsx,jsx}");
|
|
458
493
|
const { componentData, dataFiles } = await buildAppFiles(srcDirFiles, isDev2);
|
|
459
494
|
const alpineDataFile = await buildAlpineDataFile(componentData, dataFiles);
|
|
460
495
|
await buildClientSideFiles([alpineDataFile], isDev2);
|
|
461
|
-
|
|
496
|
+
fs6.removeSync(config.distTempFolder);
|
|
462
497
|
await buildCSS(disableTailwind2);
|
|
463
498
|
await buildPublicFolderSymlinks();
|
|
464
499
|
await buildOnLoadFile(componentData, isDev2);
|
|
@@ -478,7 +513,7 @@ async function buildAppFiles(files, isDev2) {
|
|
|
478
513
|
return fileName === "+config";
|
|
479
514
|
});
|
|
480
515
|
const backendFiles = files.filter((file) => extensions.find((ext) => file.endsWith(ext))).filter((file) => !file.startsWith(config.publicDir));
|
|
481
|
-
|
|
516
|
+
fs6.ensureDirSync(config.distDir);
|
|
482
517
|
await build({
|
|
483
518
|
entryPoints: backendFiles,
|
|
484
519
|
format: "esm",
|
|
@@ -503,9 +538,9 @@ async function buildAppFiles(files, isDev2) {
|
|
|
503
538
|
}
|
|
504
539
|
async function buildClientSideFiles(alpineDataFiles = [], isDev2) {
|
|
505
540
|
const tempFilePath = path5.join(config.distTempFolder, "./app.ts");
|
|
506
|
-
|
|
541
|
+
fs6.ensureFileSync(tempFilePath);
|
|
507
542
|
const pagesScriptsGlob = config.publicDir + "/scripts/pages/**/*.{js,ts}";
|
|
508
|
-
const clientFiles =
|
|
543
|
+
const clientFiles = globSync2(
|
|
509
544
|
config.publicDir + "/**/*.{js,ts}",
|
|
510
545
|
{
|
|
511
546
|
ignore: pagesScriptsGlob
|
|
@@ -521,7 +556,7 @@ async function buildClientSideFiles(alpineDataFiles = [], isDev2) {
|
|
|
521
556
|
minify: !isDev2,
|
|
522
557
|
sourcemap: isDev2 ? "inline" : false
|
|
523
558
|
});
|
|
524
|
-
const pagesFiles =
|
|
559
|
+
const pagesFiles = globSync2(pagesScriptsGlob);
|
|
525
560
|
await build({
|
|
526
561
|
entryPoints: pagesFiles || [],
|
|
527
562
|
bundle: true,
|
|
@@ -533,13 +568,13 @@ async function buildClientSideFiles(alpineDataFiles = [], isDev2) {
|
|
|
533
568
|
}
|
|
534
569
|
function writeDevServerClientSideCode(tempFilePath) {
|
|
535
570
|
const devServerPath = path5.join(xpineDistDir, "./src/static/dev-server.js");
|
|
536
|
-
const content =
|
|
537
|
-
|
|
571
|
+
const content = fs6.readFileSync(devServerPath, "utf-8");
|
|
572
|
+
fs6.appendFileSync(tempFilePath, "\n" + content);
|
|
538
573
|
}
|
|
539
574
|
function writeSpaClientSideCode(tempFilePath) {
|
|
540
575
|
const spaPath = path5.join(xpineDistDir, "./src/static/spa.js");
|
|
541
|
-
const content =
|
|
542
|
-
|
|
576
|
+
const content = fs6.readFileSync(spaPath, "utf-8");
|
|
577
|
+
fs6.appendFileSync(tempFilePath, "\n" + content);
|
|
543
578
|
}
|
|
544
579
|
async function buildAlpineDataFile(componentData, dataFiles) {
|
|
545
580
|
const output = {
|
|
@@ -585,23 +620,23 @@ async function buildAlpineDataFile(componentData, dataFiles) {
|
|
|
585
620
|
output.code.push(`Alpine.data('${dataFunction.name}', ${dataFunction.name});`);
|
|
586
621
|
}
|
|
587
622
|
const result = output.imports.join("\n") + "\n" + output.code.join("\n") + "\n" + output.end.join("\n");
|
|
588
|
-
|
|
589
|
-
|
|
623
|
+
fs6.ensureFileSync(config.alpineDataPath);
|
|
624
|
+
fs6.writeFileSync(config.alpineDataPath, result);
|
|
590
625
|
return config.alpineDataPath;
|
|
591
626
|
}
|
|
592
627
|
async function buildCSS(disableTailwind2) {
|
|
593
|
-
const cssFiles =
|
|
628
|
+
const cssFiles = globSync2(config.srcDir + "/**/*.css");
|
|
594
629
|
for (const file of cssFiles) {
|
|
595
|
-
const fileContents =
|
|
630
|
+
const fileContents = fs6.readFileSync(file, "utf-8");
|
|
596
631
|
const result = disableTailwind2 ? fileContents : await postcss([tailwindPostcss(), remove_layers_default()]).process(fileContents, { from: file });
|
|
597
632
|
const newPath = file.replace(config.srcDir, config.distDir);
|
|
598
|
-
|
|
599
|
-
|
|
633
|
+
fs6.ensureFileSync(newPath);
|
|
634
|
+
fs6.writeFileSync(newPath, result.css);
|
|
600
635
|
}
|
|
601
636
|
logSize(config.distPublicDir, "css");
|
|
602
637
|
}
|
|
603
638
|
async function buildPublicFolderSymlinks() {
|
|
604
|
-
const files =
|
|
639
|
+
const files = globSync2(config.publicDir + "/**/*.*", {
|
|
605
640
|
ignore: "/**/*.{css,js,ts,tsx,jsx}"
|
|
606
641
|
});
|
|
607
642
|
for (const file of files) {
|
|
@@ -610,19 +645,19 @@ async function buildPublicFolderSymlinks() {
|
|
|
610
645
|
const splitNewPath = newPath.split("/");
|
|
611
646
|
splitNewPath.pop();
|
|
612
647
|
const newDir = splitNewPath.join("/");
|
|
613
|
-
|
|
614
|
-
|
|
648
|
+
fs6.ensureDirSync(newDir);
|
|
649
|
+
fs6.symlinkSync(file, newPath);
|
|
615
650
|
} catch {
|
|
616
651
|
}
|
|
617
652
|
}
|
|
618
653
|
}
|
|
619
654
|
async function logSize(pathName, type, validExtensions = [".js", ".css"]) {
|
|
620
|
-
const files =
|
|
655
|
+
const files = globSync2(pathName + "/**/*" + (type === "css" ? ".css" : ""));
|
|
621
656
|
const fileSizes = files.map((file) => {
|
|
622
657
|
if (!validExtensions.find((ext) => file.endsWith(ext))) return false;
|
|
623
658
|
return {
|
|
624
659
|
file,
|
|
625
|
-
size:
|
|
660
|
+
size: fs6.statSync(file).size / (1024 * 1e3)
|
|
626
661
|
};
|
|
627
662
|
}).filter(Boolean);
|
|
628
663
|
const totalSize = fileSizes.reduce((total, current) => {
|
|
@@ -660,13 +695,14 @@ async function buildStaticFiles(config2, component, componentImport, builtCompon
|
|
|
660
695
|
return total.replace(`/[${current}]`, "");
|
|
661
696
|
}, path5.dirname(builtComponentPath)) : path5.dirname(builtComponentPath);
|
|
662
697
|
if (typeof config2?.staticPaths === "boolean") {
|
|
698
|
+
const urlPath = filePathToURLPath(outputPath);
|
|
663
699
|
try {
|
|
664
700
|
const req = { params: {} };
|
|
665
701
|
const data = config2?.data ? await config2.data(req) : null;
|
|
666
|
-
const staticComponentOutput = await componentFn({ data });
|
|
667
|
-
|
|
702
|
+
const staticComponentOutput = await componentFn({ data, routePath: urlPath });
|
|
703
|
+
fs6.writeFileSync(
|
|
668
704
|
path5.join(outputPath, "./index.html"),
|
|
669
|
-
doctypeHTML + (config2?.wrapper ? await config2.wrapper({ req, children: staticComponentOutput, config: config2, data }) : staticComponentOutput) + staticComment
|
|
705
|
+
doctypeHTML + (config2?.wrapper ? await config2.wrapper({ req, children: staticComponentOutput, config: config2, data, routePath: urlPath }) : staticComponentOutput) + staticComment
|
|
670
706
|
);
|
|
671
707
|
} catch (err) {
|
|
672
708
|
console.error(err);
|
|
@@ -681,13 +717,14 @@ async function buildStaticFiles(config2, component, componentImport, builtCompon
|
|
|
681
717
|
...componentDynamicPaths?.length ? dynamicPath : {}
|
|
682
718
|
}
|
|
683
719
|
};
|
|
684
|
-
const data = config2?.data ? await config2.data(req) : null;
|
|
685
|
-
const staticComponentOutput = await componentFn({ req, data });
|
|
686
720
|
const updatedOutDir = path5.join(outputPath, `./${componentDynamicPaths.map((key) => dynamicPath[key]).join("/")}`);
|
|
687
|
-
|
|
688
|
-
|
|
721
|
+
const urlPath = filePathToURLPath(updatedOutDir);
|
|
722
|
+
const data = config2?.data ? await config2.data(req) : null;
|
|
723
|
+
const staticComponentOutput = await componentFn({ req, data, routePath: urlPath });
|
|
724
|
+
fs6.ensureDirSync(updatedOutDir);
|
|
725
|
+
fs6.writeFileSync(
|
|
689
726
|
path5.join(updatedOutDir, "./index.html"),
|
|
690
|
-
doctypeHTML + (config2?.wrapper ? await config2.wrapper({ req, children: staticComponentOutput, config: config2, data }) : staticComponentOutput) + staticComment
|
|
727
|
+
doctypeHTML + (config2?.wrapper ? await config2.wrapper({ req, children: staticComponentOutput, config: config2, data, routePath: urlPath }) : staticComponentOutput) + staticComment
|
|
691
728
|
);
|
|
692
729
|
} catch (err) {
|
|
693
730
|
console.log("Could not build static component", component.path);
|
|
@@ -736,7 +773,7 @@ async function buildOnLoadFile(componentData, isDev2) {
|
|
|
736
773
|
}
|
|
737
774
|
`;
|
|
738
775
|
const onLoadFilePath = path5.join(config.distDir, "./__xpineOnLoad.ts");
|
|
739
|
-
|
|
776
|
+
fs6.writeFileSync(onLoadFilePath, output);
|
|
740
777
|
await build({
|
|
741
778
|
entryPoints: [onLoadFilePath],
|
|
742
779
|
format: "esm",
|
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
// src/runDevServer.ts
|
|
4
4
|
import expressWs from "express-ws";
|
|
5
5
|
import http from "http";
|
|
6
|
-
import
|
|
7
|
-
import
|
|
6
|
+
import express2 from "express";
|
|
7
|
+
import EventEmitter2 from "events";
|
|
8
8
|
import chokidar from "chokidar";
|
|
9
9
|
|
|
10
10
|
// src/scripts/build.ts
|
|
11
11
|
import path5 from "path";
|
|
12
|
-
import
|
|
12
|
+
import fs6 from "fs-extra";
|
|
13
13
|
import { build } from "esbuild";
|
|
14
14
|
|
|
15
15
|
// src/build/typescript-builder.ts
|
|
@@ -287,7 +287,7 @@ async function triggerXPineOnLoad(noCache = false) {
|
|
|
287
287
|
}
|
|
288
288
|
|
|
289
289
|
// src/scripts/build.ts
|
|
290
|
-
import { globSync } from "glob";
|
|
290
|
+
import { globSync as globSync2 } from "glob";
|
|
291
291
|
import postcss from "postcss";
|
|
292
292
|
import tailwindPostcss from "@tailwindcss/postcss";
|
|
293
293
|
|
|
@@ -328,7 +328,9 @@ var regex_default = {
|
|
|
328
328
|
dynamicRoutes: /(\[)(.*?)(\])/g,
|
|
329
329
|
isDynamicRoute: /\[(.*)\]/g,
|
|
330
330
|
endsWithTSX: /\.tsx$/,
|
|
331
|
-
endsWithJSX: /\.jsx
|
|
331
|
+
endsWithJSX: /\.jsx$/,
|
|
332
|
+
endsWithFileName: /\.(html|tsx|jsx|js|ts)$/,
|
|
333
|
+
indexFile: /index\.(html|tsx|jsx|js|ts)$/g
|
|
332
334
|
};
|
|
333
335
|
|
|
334
336
|
// src/util/config-file.ts
|
|
@@ -451,8 +453,41 @@ var staticComment = "<!-- static -->";
|
|
|
451
453
|
|
|
452
454
|
// src/scripts/build.ts
|
|
453
455
|
import ts3 from "typescript";
|
|
456
|
+
|
|
457
|
+
// src/express.ts
|
|
458
|
+
import express from "express";
|
|
459
|
+
import { globSync } from "glob";
|
|
460
|
+
|
|
461
|
+
// src/auth.ts
|
|
462
|
+
import jsonwebtoken from "jsonwebtoken";
|
|
463
|
+
var { verify, sign } = jsonwebtoken;
|
|
464
|
+
|
|
465
|
+
// src/express.ts
|
|
466
|
+
import requestIP from "request-ip";
|
|
467
|
+
import fs5 from "fs-extra";
|
|
468
|
+
import EventEmitter from "events";
|
|
469
|
+
var OnInitEmitter = class extends EventEmitter {
|
|
470
|
+
};
|
|
471
|
+
var onInitEmitter = new OnInitEmitter();
|
|
472
|
+
onInitEmitter.on("triggerOnInit", async (paths) => {
|
|
473
|
+
for (const routePath of paths) {
|
|
474
|
+
const pathImport = await import(routePath.path + `?cache=${Date.now()}`);
|
|
475
|
+
if (pathImport?.config?.onInit) await pathImport.config.onInit();
|
|
476
|
+
}
|
|
477
|
+
});
|
|
478
|
+
function filePathToURLPath(pathName, isDist = true) {
|
|
479
|
+
const result = pathName.split(isDist ? config.distPagesDir : config.pagesDir).pop().replace(regex_default.indexFile, "").replace(regex_default.endsWithFileName, "");
|
|
480
|
+
if (result.endsWith("/")) {
|
|
481
|
+
const cleanedResult = result.slice(0, -1);
|
|
482
|
+
if (!cleanedResult) return "/";
|
|
483
|
+
return cleanedResult;
|
|
484
|
+
}
|
|
485
|
+
return result;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
// src/scripts/build.ts
|
|
454
489
|
var extensions = [".ts", ".tsx"];
|
|
455
|
-
var packageJson = JSON.parse(
|
|
490
|
+
var packageJson = JSON.parse(fs6.readFileSync(config.packageJsonPath, "utf-8"));
|
|
456
491
|
var allPackages = Object.keys(packageJson.devDependencies).concat(Object.keys(packageJson.dependencies));
|
|
457
492
|
var xpineDistDir = getXPineDistDir();
|
|
458
493
|
async function buildApp(args) {
|
|
@@ -460,12 +495,12 @@ async function buildApp(args) {
|
|
|
460
495
|
const removePreviousBuild = args?.removePreviousBuild || false;
|
|
461
496
|
const disableTailwind = args?.disableTailwind || false;
|
|
462
497
|
try {
|
|
463
|
-
if (removePreviousBuild)
|
|
464
|
-
const srcDirFiles =
|
|
498
|
+
if (removePreviousBuild) fs6.removeSync(config.distDir);
|
|
499
|
+
const srcDirFiles = globSync2(config.srcDir + "/**/*.{js,ts,tsx,jsx}");
|
|
465
500
|
const { componentData, dataFiles } = await buildAppFiles(srcDirFiles, isDev);
|
|
466
501
|
const alpineDataFile = await buildAlpineDataFile(componentData, dataFiles);
|
|
467
502
|
await buildClientSideFiles([alpineDataFile], isDev);
|
|
468
|
-
|
|
503
|
+
fs6.removeSync(config.distTempFolder);
|
|
469
504
|
await buildCSS(disableTailwind);
|
|
470
505
|
await buildPublicFolderSymlinks();
|
|
471
506
|
await buildOnLoadFile(componentData, isDev);
|
|
@@ -485,7 +520,7 @@ async function buildAppFiles(files, isDev) {
|
|
|
485
520
|
return fileName === "+config";
|
|
486
521
|
});
|
|
487
522
|
const backendFiles = files.filter((file) => extensions.find((ext) => file.endsWith(ext))).filter((file) => !file.startsWith(config.publicDir));
|
|
488
|
-
|
|
523
|
+
fs6.ensureDirSync(config.distDir);
|
|
489
524
|
await build({
|
|
490
525
|
entryPoints: backendFiles,
|
|
491
526
|
format: "esm",
|
|
@@ -510,9 +545,9 @@ async function buildAppFiles(files, isDev) {
|
|
|
510
545
|
}
|
|
511
546
|
async function buildClientSideFiles(alpineDataFiles = [], isDev) {
|
|
512
547
|
const tempFilePath = path5.join(config.distTempFolder, "./app.ts");
|
|
513
|
-
|
|
548
|
+
fs6.ensureFileSync(tempFilePath);
|
|
514
549
|
const pagesScriptsGlob = config.publicDir + "/scripts/pages/**/*.{js,ts}";
|
|
515
|
-
const clientFiles =
|
|
550
|
+
const clientFiles = globSync2(
|
|
516
551
|
config.publicDir + "/**/*.{js,ts}",
|
|
517
552
|
{
|
|
518
553
|
ignore: pagesScriptsGlob
|
|
@@ -528,7 +563,7 @@ async function buildClientSideFiles(alpineDataFiles = [], isDev) {
|
|
|
528
563
|
minify: !isDev,
|
|
529
564
|
sourcemap: isDev ? "inline" : false
|
|
530
565
|
});
|
|
531
|
-
const pagesFiles =
|
|
566
|
+
const pagesFiles = globSync2(pagesScriptsGlob);
|
|
532
567
|
await build({
|
|
533
568
|
entryPoints: pagesFiles || [],
|
|
534
569
|
bundle: true,
|
|
@@ -540,13 +575,13 @@ async function buildClientSideFiles(alpineDataFiles = [], isDev) {
|
|
|
540
575
|
}
|
|
541
576
|
function writeDevServerClientSideCode(tempFilePath) {
|
|
542
577
|
const devServerPath = path5.join(xpineDistDir, "./src/static/dev-server.js");
|
|
543
|
-
const content =
|
|
544
|
-
|
|
578
|
+
const content = fs6.readFileSync(devServerPath, "utf-8");
|
|
579
|
+
fs6.appendFileSync(tempFilePath, "\n" + content);
|
|
545
580
|
}
|
|
546
581
|
function writeSpaClientSideCode(tempFilePath) {
|
|
547
582
|
const spaPath = path5.join(xpineDistDir, "./src/static/spa.js");
|
|
548
|
-
const content =
|
|
549
|
-
|
|
583
|
+
const content = fs6.readFileSync(spaPath, "utf-8");
|
|
584
|
+
fs6.appendFileSync(tempFilePath, "\n" + content);
|
|
550
585
|
}
|
|
551
586
|
async function buildAlpineDataFile(componentData, dataFiles) {
|
|
552
587
|
const output = {
|
|
@@ -592,23 +627,23 @@ async function buildAlpineDataFile(componentData, dataFiles) {
|
|
|
592
627
|
output.code.push(`Alpine.data('${dataFunction.name}', ${dataFunction.name});`);
|
|
593
628
|
}
|
|
594
629
|
const result = output.imports.join("\n") + "\n" + output.code.join("\n") + "\n" + output.end.join("\n");
|
|
595
|
-
|
|
596
|
-
|
|
630
|
+
fs6.ensureFileSync(config.alpineDataPath);
|
|
631
|
+
fs6.writeFileSync(config.alpineDataPath, result);
|
|
597
632
|
return config.alpineDataPath;
|
|
598
633
|
}
|
|
599
634
|
async function buildCSS(disableTailwind) {
|
|
600
|
-
const cssFiles =
|
|
635
|
+
const cssFiles = globSync2(config.srcDir + "/**/*.css");
|
|
601
636
|
for (const file of cssFiles) {
|
|
602
|
-
const fileContents =
|
|
637
|
+
const fileContents = fs6.readFileSync(file, "utf-8");
|
|
603
638
|
const result = disableTailwind ? fileContents : await postcss([tailwindPostcss(), remove_layers_default()]).process(fileContents, { from: file });
|
|
604
639
|
const newPath = file.replace(config.srcDir, config.distDir);
|
|
605
|
-
|
|
606
|
-
|
|
640
|
+
fs6.ensureFileSync(newPath);
|
|
641
|
+
fs6.writeFileSync(newPath, result.css);
|
|
607
642
|
}
|
|
608
643
|
logSize(config.distPublicDir, "css");
|
|
609
644
|
}
|
|
610
645
|
async function buildPublicFolderSymlinks() {
|
|
611
|
-
const files =
|
|
646
|
+
const files = globSync2(config.publicDir + "/**/*.*", {
|
|
612
647
|
ignore: "/**/*.{css,js,ts,tsx,jsx}"
|
|
613
648
|
});
|
|
614
649
|
for (const file of files) {
|
|
@@ -617,19 +652,19 @@ async function buildPublicFolderSymlinks() {
|
|
|
617
652
|
const splitNewPath = newPath.split("/");
|
|
618
653
|
splitNewPath.pop();
|
|
619
654
|
const newDir = splitNewPath.join("/");
|
|
620
|
-
|
|
621
|
-
|
|
655
|
+
fs6.ensureDirSync(newDir);
|
|
656
|
+
fs6.symlinkSync(file, newPath);
|
|
622
657
|
} catch {
|
|
623
658
|
}
|
|
624
659
|
}
|
|
625
660
|
}
|
|
626
661
|
async function logSize(pathName, type, validExtensions = [".js", ".css"]) {
|
|
627
|
-
const files =
|
|
662
|
+
const files = globSync2(pathName + "/**/*" + (type === "css" ? ".css" : ""));
|
|
628
663
|
const fileSizes = files.map((file) => {
|
|
629
664
|
if (!validExtensions.find((ext) => file.endsWith(ext))) return false;
|
|
630
665
|
return {
|
|
631
666
|
file,
|
|
632
|
-
size:
|
|
667
|
+
size: fs6.statSync(file).size / (1024 * 1e3)
|
|
633
668
|
};
|
|
634
669
|
}).filter(Boolean);
|
|
635
670
|
const totalSize = fileSizes.reduce((total, current) => {
|
|
@@ -667,13 +702,14 @@ async function buildStaticFiles(config2, component, componentImport, builtCompon
|
|
|
667
702
|
return total.replace(`/[${current}]`, "");
|
|
668
703
|
}, path5.dirname(builtComponentPath)) : path5.dirname(builtComponentPath);
|
|
669
704
|
if (typeof config2?.staticPaths === "boolean") {
|
|
705
|
+
const urlPath = filePathToURLPath(outputPath);
|
|
670
706
|
try {
|
|
671
707
|
const req = { params: {} };
|
|
672
708
|
const data = config2?.data ? await config2.data(req) : null;
|
|
673
|
-
const staticComponentOutput = await componentFn({ data });
|
|
674
|
-
|
|
709
|
+
const staticComponentOutput = await componentFn({ data, routePath: urlPath });
|
|
710
|
+
fs6.writeFileSync(
|
|
675
711
|
path5.join(outputPath, "./index.html"),
|
|
676
|
-
doctypeHTML + (config2?.wrapper ? await config2.wrapper({ req, children: staticComponentOutput, config: config2, data }) : staticComponentOutput) + staticComment
|
|
712
|
+
doctypeHTML + (config2?.wrapper ? await config2.wrapper({ req, children: staticComponentOutput, config: config2, data, routePath: urlPath }) : staticComponentOutput) + staticComment
|
|
677
713
|
);
|
|
678
714
|
} catch (err) {
|
|
679
715
|
console.error(err);
|
|
@@ -688,13 +724,14 @@ async function buildStaticFiles(config2, component, componentImport, builtCompon
|
|
|
688
724
|
...componentDynamicPaths?.length ? dynamicPath : {}
|
|
689
725
|
}
|
|
690
726
|
};
|
|
691
|
-
const data = config2?.data ? await config2.data(req) : null;
|
|
692
|
-
const staticComponentOutput = await componentFn({ req, data });
|
|
693
727
|
const updatedOutDir = path5.join(outputPath, `./${componentDynamicPaths.map((key) => dynamicPath[key]).join("/")}`);
|
|
694
|
-
|
|
695
|
-
|
|
728
|
+
const urlPath = filePathToURLPath(updatedOutDir);
|
|
729
|
+
const data = config2?.data ? await config2.data(req) : null;
|
|
730
|
+
const staticComponentOutput = await componentFn({ req, data, routePath: urlPath });
|
|
731
|
+
fs6.ensureDirSync(updatedOutDir);
|
|
732
|
+
fs6.writeFileSync(
|
|
696
733
|
path5.join(updatedOutDir, "./index.html"),
|
|
697
|
-
doctypeHTML + (config2?.wrapper ? await config2.wrapper({ req, children: staticComponentOutput, config: config2, data }) : staticComponentOutput) + staticComment
|
|
734
|
+
doctypeHTML + (config2?.wrapper ? await config2.wrapper({ req, children: staticComponentOutput, config: config2, data, routePath: urlPath }) : staticComponentOutput) + staticComment
|
|
698
735
|
);
|
|
699
736
|
} catch (err) {
|
|
700
737
|
console.log("Could not build static component", component.path);
|
|
@@ -743,7 +780,7 @@ async function buildOnLoadFile(componentData, isDev) {
|
|
|
743
780
|
}
|
|
744
781
|
`;
|
|
745
782
|
const onLoadFilePath = path5.join(config.distDir, "./__xpineOnLoad.ts");
|
|
746
|
-
|
|
783
|
+
fs6.writeFileSync(onLoadFilePath, output);
|
|
747
784
|
await build({
|
|
748
785
|
entryPoints: [onLoadFilePath],
|
|
749
786
|
format: "esm",
|
|
@@ -825,10 +862,10 @@ async function runDevServer() {
|
|
|
825
862
|
const startServer2 = (await import(config.serverDistAppPath + `?cache=${Date.now()}`)).default;
|
|
826
863
|
appServer = await startServer2();
|
|
827
864
|
}
|
|
828
|
-
const wsApp =
|
|
865
|
+
const wsApp = express2();
|
|
829
866
|
const wsServer = http.createServer(wsApp);
|
|
830
867
|
expressWs(wsApp, wsServer);
|
|
831
|
-
class RefreshEmitter extends
|
|
868
|
+
class RefreshEmitter extends EventEmitter2 {
|
|
832
869
|
}
|
|
833
870
|
;
|
|
834
871
|
const refreshEmitter = new RefreshEmitter();
|
|
@@ -851,7 +888,7 @@ function asyncServerClose(server) {
|
|
|
851
888
|
});
|
|
852
889
|
}
|
|
853
890
|
function createRebuildEmitter(delay = 500) {
|
|
854
|
-
class RebuildEmitter extends
|
|
891
|
+
class RebuildEmitter extends EventEmitter2 {
|
|
855
892
|
}
|
|
856
893
|
;
|
|
857
894
|
const rebuildEmitter = new RebuildEmitter();
|
package/dist/src/util/regex.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"regex.d.ts","sourceRoot":"","sources":["../../../src/util/regex.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"regex.d.ts","sourceRoot":"","sources":["../../../src/util/regex.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,wBAUE"}
|
package/dist/types.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ export type WrapperProps = {
|
|
|
16
16
|
children: any;
|
|
17
17
|
config: ConfigFile;
|
|
18
18
|
data?: any;
|
|
19
|
+
routePath?: string;
|
|
19
20
|
};
|
|
20
21
|
export type ConfigFile = {
|
|
21
22
|
staticPaths?: boolean | (() => Promise<{
|
|
@@ -28,6 +29,7 @@ export type PageProps = {
|
|
|
28
29
|
req: ServerRequest;
|
|
29
30
|
res: Response;
|
|
30
31
|
data: any;
|
|
32
|
+
routePath: string;
|
|
31
33
|
};
|
|
32
34
|
export type FileItem = {
|
|
33
35
|
file: string;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,MAAM,MAAM,WAAW,GAAG;IACxB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB,CAAA;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG;IACpC,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,aAAa,CAAC;IACnB,QAAQ,EAAE,GAAG,CAAC;IACd,MAAM,EAAE,UAAU,CAAC;IACnB,IAAI,CAAC,EAAE,GAAG,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,MAAM,MAAM,WAAW,GAAG;IACxB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB,CAAA;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG;IACpC,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,aAAa,CAAC;IACnB,QAAQ,EAAE,GAAG,CAAC;IACd,MAAM,EAAE,UAAU,CAAC;IACnB,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAA;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,WAAW,CAAC,EAAE,OAAO,GAAG,CAAC,MAAM,OAAO,CAAC;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,EAAE,CAAC,CAAC,CAAC;IACrE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IAChD,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;CAC7C,CAAA;AAED,MAAM,MAAM,SAAS,GAAG;IACtB,GAAG,EAAE,aAAa,CAAC;IACnB,GAAG,EAAE,QAAQ,CAAC;IACd,IAAI,EAAE,GAAG,CAAC;IACV,SAAS,EAAE,MAAM,CAAC;CACnB,CAAA;AAED,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,EAAE,EAAE,CAAC,UAAU,CAAC;CACvB,CAAA"}
|
package/package.json
CHANGED
package/types.ts
CHANGED
|
@@ -20,6 +20,7 @@ export type WrapperProps = {
|
|
|
20
20
|
children: any;
|
|
21
21
|
config: ConfigFile;
|
|
22
22
|
data?: any;
|
|
23
|
+
routePath?: string;
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
export type ConfigFile = {
|
|
@@ -32,6 +33,7 @@ export type PageProps = {
|
|
|
32
33
|
req: ServerRequest;
|
|
33
34
|
res: Response;
|
|
34
35
|
data: any;
|
|
36
|
+
routePath: string;
|
|
35
37
|
}
|
|
36
38
|
|
|
37
39
|
export type FileItem = {
|