vite-react-ssg 0.6.2 → 0.7.0-beta.1

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/node.mjs CHANGED
@@ -2,14 +2,17 @@ import { join, isAbsolute, parse, dirname } from 'node:path';
2
2
  import { createRequire } from 'node:module';
3
3
  import { gray, yellow, blue, dim, cyan, red, green, reset, bold, bgLightCyan } from 'kolorist';
4
4
  import fs from 'fs-extra';
5
- import { resolveConfig, build as build$1, mergeConfig, version as version$1, createServer } from 'vite';
5
+ import { resolveConfig, build as build$1, mergeConfig, version as version$1, send, createServer } from 'vite';
6
6
  import { JSDOM } from 'jsdom';
7
- import { s as serializeState } from './shared/vite-react-ssg.a009fbf1.mjs';
7
+ import { s as serializeState } from './shared/vite-react-ssg.579feabb.mjs';
8
+ import { a as withTrailingSlash, r as removeLeadingSlash, c as convertRoutesToDataRoutes, j as joinUrlSegments } from './shared/vite-react-ssg.054e813a.mjs';
8
9
  import { readFileSync } from 'node:fs';
9
10
  import React from 'react';
10
11
  import { HelmetProvider } from 'react-helmet-async';
11
- import { Writable } from 'node:stream';
12
+ import { Writable, Readable } from 'node:stream';
12
13
  import { renderToPipeableStream } from 'react-dom/server';
14
+ import { matchRoutes, json } from 'react-router-dom';
15
+ import { once } from 'node:events';
13
16
 
14
17
  function getDefaultExportFromCjs (x) {
15
18
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
@@ -912,23 +915,6 @@ function createRequest(path) {
912
915
  url.pathname = path;
913
916
  return new Request(url.href);
914
917
  }
915
- function joinUrlSegments(a, b) {
916
- if (!a || !b)
917
- return a || b || "";
918
- if (a[a.length - 1] === "/")
919
- a = a.substring(0, a.length - 1);
920
- if (b[0] !== "/")
921
- b = `/${b}`;
922
- return a + b;
923
- }
924
- function removeLeadingSlash(str) {
925
- return str[0] === "/" ? str.slice(1) : str;
926
- }
927
- function withTrailingSlash(path) {
928
- if (path[path.length - 1] !== "/")
929
- return `${path}/`;
930
- return path;
931
- }
932
918
  const dynamicRE = /[:*?]/;
933
919
  function isDynamicSegmentsRoute(route) {
934
920
  if (!route)
@@ -1043,6 +1029,7 @@ function extractHelmet(context, styleCollector) {
1043
1029
  return { htmlAttributes, bodyAttributes, metaAttributes, styleTag };
1044
1030
  }
1045
1031
 
1032
+ const SCRIPT_COMMENT_PLACEHOLDER = "/* SCRIPT_COMMENT_PLACEHOLDER */";
1046
1033
  async function renderHTML({
1047
1034
  rootContainerId,
1048
1035
  indexHTML,
@@ -1054,6 +1041,8 @@ async function renderHTML({
1054
1041
  }) {
1055
1042
  const stateScript = initialState ? `
1056
1043
  <script>window.__INITIAL_STATE__=${initialState}<\/script>` : "";
1044
+ const scriptPlaceHolder = `
1045
+ <script>${SCRIPT_COMMENT_PLACEHOLDER}<\/script>`;
1057
1046
  const headStartTag = "<head>";
1058
1047
  const metaTags = metaAttributes.join("");
1059
1048
  indexHTML = indexHTML.replace(headStartTag, headStartTag + metaTags);
@@ -1065,7 +1054,7 @@ async function renderHTML({
1065
1054
  if (indexHTML.includes(container)) {
1066
1055
  return indexHTML.replace(
1067
1056
  container,
1068
- `<div id="${rootContainerId}" data-server-rendered="true">${appHTML}</div>${stateScript}`
1057
+ `<div id="${rootContainerId}" data-server-rendered="true">${appHTML}</div>${stateScript}${scriptPlaceHolder}`
1069
1058
  );
1070
1059
  }
1071
1060
  const html5Parser = await import('html5parser');
@@ -1086,7 +1075,7 @@ async function renderHTML({
1086
1075
  return renderedOutput;
1087
1076
  }
1088
1077
  async function detectEntry(root) {
1089
- const scriptSrcReg = /<script(?:.*?)src=["'](.+?)["'](?!<)(?:.*)\>(?:[\n\r\s]*?)(?:<\/script>)/img;
1078
+ const scriptSrcReg = /<script(?:.*?)src=["'](.+?)["'](?!<)(?:.*)\>(?:[\n\r\s]*?)(?:<\/script>)/gim;
1090
1079
  const html = await fs.readFile(join(root, "index.html"), "utf-8");
1091
1080
  const scripts = [...html.matchAll(scriptSrcReg)];
1092
1081
  const [, entry] = scripts.find((matchResult) => {
@@ -1159,7 +1148,8 @@ async function build(ssgOptions = {}, viteConfig = {}) {
1159
1148
  const config = await resolveConfig(viteConfig, "build", mode, mode);
1160
1149
  const cwd = process.cwd();
1161
1150
  const root = config.root || cwd;
1162
- const ssgOut = join(root, ".vite-react-ssg-temp", Math.random().toString(36).substring(2, 12));
1151
+ const hash = Math.random().toString(36).substring(2, 12);
1152
+ const ssgOut = join(root, ".vite-react-ssg-temp", hash);
1163
1153
  const outDir = config.build.outDir || "dist";
1164
1154
  const out = isAbsolute(outDir) ? outDir : join(root, outDir);
1165
1155
  const configBase = config.base;
@@ -1198,7 +1188,8 @@ async function build(ssgOptions = {}, viteConfig = {}) {
1198
1188
  }
1199
1189
  }
1200
1190
  },
1201
- mode: config.mode
1191
+ mode: config.mode,
1192
+ ssr: { noExternal: ["vite-react-ssg"] }
1202
1193
  }));
1203
1194
  if (mock) {
1204
1195
  const { jsdomGlobal } = await import('./chunks/jsdomGlobal.mjs');
@@ -1223,7 +1214,8 @@ async function build(ssgOptions = {}, viteConfig = {}) {
1223
1214
  }
1224
1215
  }
1225
1216
  },
1226
- mode: config.mode
1217
+ mode: config.mode,
1218
+ ssr: { noExternal: ["vite-react-ssg"] }
1227
1219
  }));
1228
1220
  const prefix = format === "esm" && process.platform === "win32" ? "file://" : "";
1229
1221
  const ext = format === "esm" ? ".mjs" : ".cjs";
@@ -1247,6 +1239,7 @@ async function build(ssgOptions = {}, viteConfig = {}) {
1247
1239
  indexHTML = rewriteScripts(indexHTML, script);
1248
1240
  const queue = new PQueue({ concurrency });
1249
1241
  const crittersQueue = new PQueue({ concurrency: 1 });
1242
+ const staticLoaderDataManifest = {};
1250
1243
  for (const path of routesPaths) {
1251
1244
  queue.add(async () => {
1252
1245
  try {
@@ -1256,7 +1249,8 @@ async function build(ssgOptions = {}, viteConfig = {}) {
1256
1249
  const transformedIndexHTML = await onBeforePageRender?.(path, indexHTML, appCtx) || indexHTML;
1257
1250
  const fetchUrl = `${withTrailingSlash(base)}${removeLeadingSlash(path)}`;
1258
1251
  const request = createRequest(fetchUrl);
1259
- const { appHTML, bodyAttributes, htmlAttributes, metaAttributes, styleTag } = await render(app ?? [...routes2], request, styleCollector, base);
1252
+ const { appHTML, bodyAttributes, htmlAttributes, metaAttributes, styleTag, routerContext } = await render(app ?? [...routes2], request, styleCollector, base);
1253
+ staticLoaderDataManifest[path] = routerContext?.loaderData;
1260
1254
  await triggerOnSSRAppRendered?.(path, appHTML, appCtx);
1261
1255
  const renderedHTML = await renderHTML({
1262
1256
  rootContainerId,
@@ -1272,6 +1266,7 @@ async function build(ssgOptions = {}, viteConfig = {}) {
1272
1266
  renderPreloadLinks(jsdom.window.document, modules, ssrManifest);
1273
1267
  const html = jsdom.serialize();
1274
1268
  let transformed = await onPageRendered?.(path, html, appCtx) || html;
1269
+ transformed = transformed.replace(SCRIPT_COMMENT_PLACEHOLDER, `window.__VITE_REACT_SSG_HASH__ = '${hash}'`);
1275
1270
  if (critters) {
1276
1271
  transformed = await crittersQueue.add(() => critters.process(transformed));
1277
1272
  transformed = transformed.replace(/<link\srel="stylesheet"/g, '<link rel="stylesheet" crossorigin');
@@ -1293,6 +1288,7 @@ ${err.stack}`);
1293
1288
  });
1294
1289
  }
1295
1290
  await queue.start().onIdle();
1291
+ await fs.writeFile(join(out, `static-loader-data-manifest-${hash}.json`), JSON.stringify(staticLoaderDataManifest, null, 2));
1296
1292
  await fs.remove(join(root, ".vite-react-ssg-temp"));
1297
1293
  const pwaPlugin = config.plugins.find((i) => i.name === "vite-plugin-pwa")?.api;
1298
1294
  if (pwaPlugin && !pwaPlugin.disabled && pwaPlugin.generateSW) {
@@ -1390,6 +1386,201 @@ function fromNodeRequest(nodeReq) {
1390
1386
  };
1391
1387
  return new Request(url.href, init);
1392
1388
  }
1389
+ async function toNodeRequest(res, nodeRes) {
1390
+ nodeRes.statusCode = res.status;
1391
+ nodeRes.statusMessage = res.statusText;
1392
+ for (const [name, value] of res.headers) {
1393
+ nodeRes.setHeader(name, value);
1394
+ }
1395
+ if (res.body) {
1396
+ const responseBody = res.body;
1397
+ const readable = Readable.from(responseBody);
1398
+ readable.pipe(nodeRes);
1399
+ await once(readable, "end");
1400
+ } else {
1401
+ nodeRes.end();
1402
+ }
1403
+ }
1404
+
1405
+ function ssrServerPlugin({
1406
+ template,
1407
+ ssrEntry,
1408
+ onBeforePageRender,
1409
+ entry,
1410
+ rootContainerId,
1411
+ onPageRendered
1412
+ }) {
1413
+ return {
1414
+ name: "vite-react-ssg:dev-server-remix",
1415
+ configureServer(server) {
1416
+ const renderMiddleware = async (req, res, _next) => {
1417
+ try {
1418
+ const url = req.originalUrl;
1419
+ const createRoot = await server.ssrLoadModule(ssrEntry).then((m) => m.createRoot);
1420
+ const appCtx = await createRoot(false, url);
1421
+ const { routes, getStyleCollector, base, app } = appCtx;
1422
+ const searchParams = new URLSearchParams(url.split("?")[1]);
1423
+ if (!app && searchParams.has("_data")) {
1424
+ const request = fromNodeRequest(req);
1425
+ const url2 = new URL(request.url);
1426
+ const routeId = decodeURIComponent(searchParams.get("_data"));
1427
+ const matches = matchRoutes(
1428
+ convertRoutesToDataRoutes([...routes], (route) => route),
1429
+ {
1430
+ pathname: url2.pathname,
1431
+ search: url2.search,
1432
+ hash: url2.hash,
1433
+ state: null,
1434
+ key: "default"
1435
+ },
1436
+ base
1437
+ );
1438
+ if (!matches) {
1439
+ res.statusCode = 404;
1440
+ res.end(`Route not found: ${routeId}`);
1441
+ return;
1442
+ }
1443
+ const match = matches.find((m) => m.route.id === routeId);
1444
+ if (!match) {
1445
+ res.statusCode = 404;
1446
+ res.end(`Route not found: ${routeId}`);
1447
+ return;
1448
+ }
1449
+ const loader = match.route.loader ?? await match.route.lazy?.().then((m) => m.loader);
1450
+ if (!loader) {
1451
+ res.statusCode = 200;
1452
+ res.end(`There is no loader for the route: ${routeId}`);
1453
+ return;
1454
+ }
1455
+ const response = await callRouteLoader({
1456
+ loader,
1457
+ params: match.params,
1458
+ request,
1459
+ routeId
1460
+ });
1461
+ await toNodeRequest(response, res);
1462
+ return;
1463
+ }
1464
+ const indexHTML = await server.transformIndexHtml(url, template);
1465
+ const transformedIndexHTML = await onBeforePageRender?.(url, indexHTML, appCtx) || indexHTML;
1466
+ const styleCollector = getStyleCollector ? await getStyleCollector() : null;
1467
+ const { appHTML, bodyAttributes, htmlAttributes, metaAttributes, styleTag, routerContext } = await render(app ?? [...routes], fromNodeRequest(req), styleCollector, base);
1468
+ metaAttributes.push(styleTag);
1469
+ const matchesEntries = routerContext?.matches.map((match) => match.route.entry).filter((entry2) => !!entry2).map((entry2) => entry2[0] === "/" ? entry2 : `/${entry2}`) ?? [];
1470
+ const mods = await Promise.all(
1471
+ [ssrEntry, entry, ...matchesEntries].map(async (entry2) => await server.moduleGraph.getModuleByUrl(entry2))
1472
+ );
1473
+ const assetsUrls = /* @__PURE__ */ new Set();
1474
+ const collectAssets = async (mod) => {
1475
+ if (!mod || !mod?.ssrTransformResult)
1476
+ return;
1477
+ const { deps = [], dynamicDeps = [] } = mod?.ssrTransformResult;
1478
+ const allDeps = [...deps, ...dynamicDeps];
1479
+ for (const dep of allDeps) {
1480
+ if (dep.endsWith(".css")) {
1481
+ assetsUrls.add(dep);
1482
+ } else if (dep.endsWith(".ts") || dep.endsWith(".tsx")) {
1483
+ const depModule = await server.moduleGraph.getModuleByUrl(dep);
1484
+ depModule && await collectAssets(depModule);
1485
+ }
1486
+ }
1487
+ };
1488
+ await Promise.all(mods.map(async (mod) => collectAssets(mod)));
1489
+ const preloadLink = [...assetsUrls].map((item) => createLink$1(joinUrlSegments(server.config.base, item)));
1490
+ metaAttributes.push(...preloadLink);
1491
+ const renderedHTML = await renderHTML({
1492
+ rootContainerId,
1493
+ appHTML,
1494
+ indexHTML: transformedIndexHTML,
1495
+ metaAttributes,
1496
+ bodyAttributes,
1497
+ htmlAttributes,
1498
+ initialState: null
1499
+ });
1500
+ const transformed = await onPageRendered?.(url, renderedHTML, appCtx) || renderedHTML;
1501
+ res.statusCode = 200;
1502
+ res.setHeader("Content-Type", "text/html");
1503
+ const isDev = "pluginContainer" in server;
1504
+ const headers = isDev ? server.config.server.headers : server.config.preview.headers;
1505
+ send(req, res, transformed, "html", { headers });
1506
+ } catch (e) {
1507
+ server.ssrFixStacktrace(e);
1508
+ console.error(`[vite-react-ssg] error: ${e.stack}`);
1509
+ res.statusCode = 500;
1510
+ res.end(e.stack);
1511
+ }
1512
+ };
1513
+ return () => {
1514
+ server.middlewares.use(renderMiddleware);
1515
+ };
1516
+ }
1517
+ };
1518
+ }
1519
+ async function callRouteLoader({
1520
+ // loadContext,
1521
+ loader,
1522
+ params,
1523
+ request,
1524
+ routeId
1525
+ // singleFetch,
1526
+ // response,
1527
+ }) {
1528
+ const result = await loader({
1529
+ request: stripDataParam(stripIndexParam(request)),
1530
+ // context: loadContext,
1531
+ params
1532
+ // Only provided when single fetch is enabled, and made available via
1533
+ // `defineLoader` types, not `LoaderFunctionArgs`
1534
+ // ...(singleFetch ? { response } : null),
1535
+ });
1536
+ if (result === void 0) {
1537
+ throw new Error(
1538
+ `You defined a loader for route "${routeId}" but didn't return anything from your \`loader\` function. Please return a value or \`null\`.`
1539
+ );
1540
+ }
1541
+ return isResponse(result) ? result : json(result);
1542
+ }
1543
+ function isResponse(value) {
1544
+ return value != null && typeof value.status === "number" && typeof value.statusText === "string" && typeof value.headers === "object" && typeof value.body !== "undefined";
1545
+ }
1546
+ function stripIndexParam(request) {
1547
+ const url = new URL(request.url);
1548
+ const indexValues = url.searchParams.getAll("index");
1549
+ url.searchParams.delete("index");
1550
+ const indexValuesToKeep = [];
1551
+ for (const indexValue of indexValues) {
1552
+ if (indexValue) {
1553
+ indexValuesToKeep.push(indexValue);
1554
+ }
1555
+ }
1556
+ for (const toKeep of indexValuesToKeep) {
1557
+ url.searchParams.append("index", toKeep);
1558
+ }
1559
+ const init = {
1560
+ method: request.method,
1561
+ body: request.body,
1562
+ headers: request.headers,
1563
+ signal: request.signal
1564
+ };
1565
+ if (init.body) {
1566
+ init.duplex = "half";
1567
+ }
1568
+ return new Request(url.href, init);
1569
+ }
1570
+ function stripDataParam(request) {
1571
+ const url = new URL(request.url);
1572
+ url.searchParams.delete("_data");
1573
+ const init = {
1574
+ method: request.method,
1575
+ body: request.body,
1576
+ headers: request.headers,
1577
+ signal: request.signal
1578
+ };
1579
+ if (init.body) {
1580
+ init.duplex = "half";
1581
+ }
1582
+ return new Request(url.href, init);
1583
+ }
1393
1584
 
1394
1585
  async function dev(ssgOptions = {}, viteConfig = {}, customOptions) {
1395
1586
  const mode = process.env.MODE || process.env.NODE_ENV || ssgOptions.mode || "development";
@@ -1424,66 +1615,14 @@ ${err.stack}`
1424
1615
  ...viteConfig,
1425
1616
  plugins: [
1426
1617
  ...viteConfig.plugins ?? [],
1427
- {
1428
- name: "vite-react-ssg:dev-server-remix",
1429
- configureServer(server) {
1430
- return () => {
1431
- server.middlewares.use(async (req, res, _next) => {
1432
- try {
1433
- const url = req.originalUrl;
1434
- const indexHTML = await viteServer.transformIndexHtml(url, template);
1435
- const createRoot = await viteServer.ssrLoadModule(ssrEntry).then((m) => m.createRoot);
1436
- const appCtx = await createRoot(false, url);
1437
- const { routes, getStyleCollector, base, app } = appCtx;
1438
- const transformedIndexHTML = await onBeforePageRender?.(url, indexHTML, appCtx) || indexHTML;
1439
- const styleCollector = getStyleCollector ? await getStyleCollector() : null;
1440
- const { appHTML, bodyAttributes, htmlAttributes, metaAttributes, styleTag, routerContext } = await render(app ?? [...routes], fromNodeRequest(req), styleCollector, base);
1441
- metaAttributes.push(styleTag);
1442
- const matchesEntries = routerContext?.matches.map((match) => match.route.entry).filter((entry2) => !!entry2).map((entry2) => entry2[0] === "/" ? entry2 : `/${entry2}`) ?? [];
1443
- const mods = await Promise.all(
1444
- [ssrEntry, entry, ...matchesEntries].map(async (entry2) => await viteServer.moduleGraph.getModuleByUrl(entry2))
1445
- );
1446
- const assetsUrls = /* @__PURE__ */ new Set();
1447
- const collectAssets = async (mod) => {
1448
- if (!mod || !mod?.ssrTransformResult)
1449
- return;
1450
- const { deps = [], dynamicDeps = [] } = mod?.ssrTransformResult;
1451
- const allDeps = [...deps, ...dynamicDeps];
1452
- for (const dep of allDeps) {
1453
- if (dep.endsWith(".css")) {
1454
- assetsUrls.add(dep);
1455
- } else if (dep.endsWith(".ts") || dep.endsWith(".tsx")) {
1456
- const depModule = await viteServer.moduleGraph.getModuleByUrl(dep);
1457
- depModule && await collectAssets(depModule);
1458
- }
1459
- }
1460
- };
1461
- await Promise.all(mods.map(async (mod) => collectAssets(mod)));
1462
- const preloadLink = [...assetsUrls].map((item) => createLink$1(joinUrlSegments(config.base, item)));
1463
- metaAttributes.push(...preloadLink);
1464
- const renderedHTML = await renderHTML({
1465
- rootContainerId,
1466
- appHTML,
1467
- indexHTML: transformedIndexHTML,
1468
- metaAttributes,
1469
- bodyAttributes,
1470
- htmlAttributes,
1471
- initialState: null
1472
- });
1473
- const transformed = await onPageRendered?.(url, renderedHTML, appCtx) || renderedHTML;
1474
- res.statusCode = 200;
1475
- res.setHeader("Content-Type", "text/html");
1476
- res.end(transformed);
1477
- } catch (e) {
1478
- viteServer.ssrFixStacktrace(e);
1479
- console.error(`[vite-react-ssg] error: ${e.stack}`);
1480
- res.statusCode = 500;
1481
- res.end(e.stack);
1482
- }
1483
- });
1484
- };
1485
- }
1486
- }
1618
+ ssrServerPlugin({
1619
+ template,
1620
+ ssrEntry,
1621
+ onBeforePageRender,
1622
+ onPageRendered,
1623
+ entry,
1624
+ rootContainerId
1625
+ })
1487
1626
  ]
1488
1627
  });
1489
1628
  await viteServer.listen();
@@ -0,0 +1,72 @@
1
+ 'use strict';
2
+
3
+ function joinUrlSegments(a, b) {
4
+ if (!a || !b)
5
+ return a || b || "";
6
+ if (a[a.length - 1] === "/")
7
+ a = a.substring(0, a.length - 1);
8
+ if (b[0] !== "/")
9
+ b = `/${b}`;
10
+ return a + b;
11
+ }
12
+ function removeLeadingSlash(str) {
13
+ return str[0] === "/" ? str.slice(1) : str;
14
+ }
15
+ function stripBase(path, base) {
16
+ if (path === base)
17
+ return "/";
18
+ const devBase = withTrailingSlash(base);
19
+ return path.startsWith(devBase) ? path.slice(devBase.length - 1) : path;
20
+ }
21
+ function withTrailingSlash(path) {
22
+ if (path[path.length - 1] !== "/")
23
+ return `${path}/`;
24
+ return path;
25
+ }
26
+ function withLeadingSlash(path) {
27
+ if (path[0] !== "/")
28
+ return `/${path}`;
29
+ return path;
30
+ }
31
+
32
+ function convertRoutesToDataRoutes(routes, mapRouteProperties, parentPath = []) {
33
+ return routes.map((route, index) => {
34
+ const treePath = [...parentPath, String(index)];
35
+ const id = typeof route.id === "string" ? route.id : treePath.join("-");
36
+ route.id = id;
37
+ if (isIndexRoute(route)) {
38
+ const indexRoute = {
39
+ ...route,
40
+ ...mapRouteProperties(route),
41
+ id
42
+ };
43
+ return indexRoute;
44
+ } else {
45
+ const pathOrLayoutRoute = {
46
+ ...route,
47
+ ...mapRouteProperties(route),
48
+ id,
49
+ children: void 0
50
+ };
51
+ if (route.children) {
52
+ pathOrLayoutRoute.children = convertRoutesToDataRoutes(
53
+ route.children,
54
+ mapRouteProperties,
55
+ treePath
56
+ // manifest,
57
+ );
58
+ }
59
+ return pathOrLayoutRoute;
60
+ }
61
+ });
62
+ }
63
+ function isIndexRoute(route) {
64
+ return route.index === true;
65
+ }
66
+
67
+ exports.convertRoutesToDataRoutes = convertRoutesToDataRoutes;
68
+ exports.joinUrlSegments = joinUrlSegments;
69
+ exports.removeLeadingSlash = removeLeadingSlash;
70
+ exports.stripBase = stripBase;
71
+ exports.withLeadingSlash = withLeadingSlash;
72
+ exports.withTrailingSlash = withTrailingSlash;
@@ -0,0 +1,65 @@
1
+ function joinUrlSegments(a, b) {
2
+ if (!a || !b)
3
+ return a || b || "";
4
+ if (a[a.length - 1] === "/")
5
+ a = a.substring(0, a.length - 1);
6
+ if (b[0] !== "/")
7
+ b = `/${b}`;
8
+ return a + b;
9
+ }
10
+ function removeLeadingSlash(str) {
11
+ return str[0] === "/" ? str.slice(1) : str;
12
+ }
13
+ function stripBase(path, base) {
14
+ if (path === base)
15
+ return "/";
16
+ const devBase = withTrailingSlash(base);
17
+ return path.startsWith(devBase) ? path.slice(devBase.length - 1) : path;
18
+ }
19
+ function withTrailingSlash(path) {
20
+ if (path[path.length - 1] !== "/")
21
+ return `${path}/`;
22
+ return path;
23
+ }
24
+ function withLeadingSlash(path) {
25
+ if (path[0] !== "/")
26
+ return `/${path}`;
27
+ return path;
28
+ }
29
+
30
+ function convertRoutesToDataRoutes(routes, mapRouteProperties, parentPath = []) {
31
+ return routes.map((route, index) => {
32
+ const treePath = [...parentPath, String(index)];
33
+ const id = typeof route.id === "string" ? route.id : treePath.join("-");
34
+ route.id = id;
35
+ if (isIndexRoute(route)) {
36
+ const indexRoute = {
37
+ ...route,
38
+ ...mapRouteProperties(route),
39
+ id
40
+ };
41
+ return indexRoute;
42
+ } else {
43
+ const pathOrLayoutRoute = {
44
+ ...route,
45
+ ...mapRouteProperties(route),
46
+ id,
47
+ children: void 0
48
+ };
49
+ if (route.children) {
50
+ pathOrLayoutRoute.children = convertRoutesToDataRoutes(
51
+ route.children,
52
+ mapRouteProperties,
53
+ treePath
54
+ // manifest,
55
+ );
56
+ }
57
+ return pathOrLayoutRoute;
58
+ }
59
+ });
60
+ }
61
+ function isIndexRoute(route) {
62
+ return route.index === true;
63
+ }
64
+
65
+ export { withTrailingSlash as a, convertRoutesToDataRoutes as c, joinUrlSegments as j, removeLeadingSlash as r, stripBase as s, withLeadingSlash as w };
@@ -1,4 +1,4 @@
1
- const UNSAFE_CHARS_REGEXP = /[<>\/\u2028\u2029]/g;
1
+ const UNSAFE_CHARS_REGEXP = /[<>/\u2028\u2029]/g;
2
2
  const ESCAPED_CHARS = {
3
3
  "<": "\\u003C",
4
4
  ">": "\\u003E",
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- const UNSAFE_CHARS_REGEXP = /[<>\/\u2028\u2029]/g;
3
+ const UNSAFE_CHARS_REGEXP = /[<>/\u2028\u2029]/g;
4
4
  const ESCAPED_CHARS = {
5
5
  "<": "\\u003C",
6
6
  ">": "\\u003E",
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "vite-react-ssg",
3
3
  "type": "module",
4
- "version": "0.6.2",
5
- "packageManager": "pnpm@8.6.6",
4
+ "version": "0.7.0-beta.1",
5
+ "packageManager": "pnpm@9.4.0",
6
6
  "description": "",
7
7
  "author": "Riri <Daydreamerriri@outlook.com>",
8
8
  "license": "MIT",
@@ -77,7 +77,6 @@
77
77
  "typecheck": "tsc --noEmit"
78
78
  },
79
79
  "peerDependencies": {
80
- "@childrentime/devcert": "*",
81
80
  "critters": "^0.0.19",
82
81
  "prettier": "*",
83
82
  "react": "^18.0.0",
@@ -87,9 +86,6 @@
87
86
  "vite": "^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0"
88
87
  },
89
88
  "peerDependenciesMeta": {
90
- "@childrentime/devcert": {
91
- "optional": true
92
- },
93
89
  "critters": {
94
90
  "optional": true
95
91
  },
@@ -108,14 +104,13 @@
108
104
  "fs-extra": "^11.2.0",
109
105
  "html-minifier": "^4.0.0",
110
106
  "html5parser": "^2.0.2",
111
- "jsdom": "^24.0.0",
107
+ "jsdom": "^24.1.0",
112
108
  "kolorist": "^1.8.0",
113
109
  "react-helmet-async": "^1.3.0",
114
110
  "yargs": "^17.7.2"
115
111
  },
116
112
  "devDependencies": {
117
- "@childrentime/devcert": "^1.2.5",
118
- "@ririd/eslint-config": "^1.1.0",
113
+ "@ririd/eslint-config": "^1.3.2",
119
114
  "@types/fs-extra": "^11.0.1",
120
115
  "@types/html-minifier": "^4.0.2",
121
116
  "@types/jsdom": "^21.1.1",
@@ -135,10 +130,10 @@
135
130
  "react-router-dom": "^6.15.0",
136
131
  "rimraf": "5.0.1",
137
132
  "styled-components": "6.0.5",
138
- "typescript": "5.1.6",
133
+ "typescript": "^5.5.2",
139
134
  "unbuild": "^2.0.0",
140
- "vite": "^5.0.12",
135
+ "vite": "^5.3.1",
141
136
  "vite-plugin-pwa": "^0.17.4",
142
- "vitest": "1.0.4"
137
+ "vitest": "1.6.0"
143
138
  }
144
139
  }