@qwik.dev/router 2.0.0-beta.40 → 2.0.0-beta.41
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/lib/adapters/cloudflare-pages/vite/index.mjs +1 -1
- package/lib/adapters/shared/vite/index.mjs +12 -5
- package/lib/chunks/fs.mjs +8 -1
- package/lib/chunks/head.qwik.mjs +12 -27
- package/lib/chunks/user-response.mjs +26 -3
- package/lib/index.d.ts +5 -4
- package/lib/index.qwik.mjs +10 -3
- package/lib/middleware/cloudflare-pages/index.mjs +8 -3
- package/lib/middleware/request-handler/index.mjs +1 -13
- package/lib/vite/index.mjs +27 -15
- package/package.json +3 -7
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as ensureSlash } from "../../../chunks/pathname.mjs";
|
|
2
2
|
import { viteAdapter } from "../../shared/vite/index.mjs";
|
|
3
|
-
import {
|
|
3
|
+
import { y as normalizePathSlash } from "../../../chunks/fs.mjs";
|
|
4
4
|
import fs from "node:fs";
|
|
5
5
|
import { join, relative } from "node:path";
|
|
6
6
|
/** @public */ function cloudflarePagesAdapter(opts = {}) {
|
|
@@ -31,21 +31,27 @@ var injectStatics = async (staticPathsCode, outDir) => {
|
|
|
31
31
|
await walk(outDir);
|
|
32
32
|
await Promise.all(promises);
|
|
33
33
|
};
|
|
34
|
-
/** Cleans the client output SSG results if needed and injects the SSG metadata into the build output */ async function postBuild(clientOutDir, serverOutDir, pathName, userStaticPaths, cleanStatic) {
|
|
34
|
+
/** Cleans the client output SSG results if needed and injects the SSG metadata into the build output */ async function postBuild(clientOutDir, serverOutDir, pathName, userStaticPaths, cleanStatic, noTrailingSlash) {
|
|
35
35
|
if (pathName && !pathName.endsWith("/")) pathName = ensureSlash(pathName);
|
|
36
36
|
const pathNameBase = pathName || "/";
|
|
37
37
|
const ignorePathnames = /* @__PURE__ */ new Set([pathNameBase + (globalThis.__QWIK_BUILD_DIR__ || "build") + "/", pathNameBase + (globalThis.__QWIK_ASSETS_DIR__ || "assets") + "/"]);
|
|
38
|
-
const
|
|
38
|
+
const getStaticPathname = (pathname) => {
|
|
39
|
+
pathname = ensureSlash(pathname);
|
|
40
|
+
if (noTrailingSlash && pathname !== pathNameBase) return pathname.slice(0, -1);
|
|
41
|
+
return pathname;
|
|
42
|
+
};
|
|
43
|
+
const staticPaths = new Set(userStaticPaths.map(getStaticPathname));
|
|
39
44
|
const loadItem = async (fsDir, fsName, pathname) => {
|
|
40
45
|
pathname = ensureSlash(pathname);
|
|
41
46
|
if (ignorePathnames.has(pathname)) return;
|
|
42
47
|
const fsPath = join(fsDir, fsName);
|
|
43
48
|
if (fsName === "index.html") {
|
|
44
|
-
if (!staticPaths.has(pathname) && cleanStatic) await fs.promises.unlink(fsPath);
|
|
49
|
+
if (!staticPaths.has(getStaticPathname(pathname)) && cleanStatic) await fs.promises.unlink(fsPath);
|
|
45
50
|
return;
|
|
46
51
|
}
|
|
47
52
|
if (LOADER_REGEX.test("/" + fsName)) {
|
|
48
|
-
|
|
53
|
+
const staticPathname = getStaticPathname(pathname);
|
|
54
|
+
if (staticPaths.has(staticPathname)) staticPaths.add(ensureSlash(staticPathname) + fsName);
|
|
49
55
|
else if (cleanStatic) await fs.promises.unlink(fsPath);
|
|
50
56
|
return;
|
|
51
57
|
}
|
|
@@ -217,6 +223,7 @@ var QWIK_SSG_WORKER_ENTRY_RESOLVED = "\0@qwik-ssg-worker-entry";
|
|
|
217
223
|
const basePathname = qwikRouterPlugin.api.getBasePathname();
|
|
218
224
|
const clientOutDir = qwikVitePlugin.api.getClientOutDir();
|
|
219
225
|
const clientPublicOutDir = qwikVitePlugin.api.getClientPublicOutDir();
|
|
226
|
+
const noTrailingSlash = builder.config.define?.["globalThis.__NO_TRAILING_SLASH__"] === "true";
|
|
220
227
|
const ssgEnv = builder.environments.ssg;
|
|
221
228
|
const ssgOutDir = ssgOutDirFor(builder.config.root);
|
|
222
229
|
if (ssgEnv && clientOutDir && clientPublicOutDir) {
|
|
@@ -248,7 +255,7 @@ var QWIK_SSG_WORKER_ENTRY_RESOLVED = "\0@qwik-ssg-worker-entry";
|
|
|
248
255
|
force: true
|
|
249
256
|
});
|
|
250
257
|
}
|
|
251
|
-
await postBuild(clientPublicOutDir, serverOutDir, basePathname, staticPaths, !!opts.cleanStaticGenerated);
|
|
258
|
+
await postBuild(clientPublicOutDir, serverOutDir, basePathname, staticPaths, !!opts.cleanStaticGenerated, noTrailingSlash);
|
|
252
259
|
if (typeof opts.generate === "function") await opts.generate({
|
|
253
260
|
outputEntries,
|
|
254
261
|
serverOutDir,
|
package/lib/chunks/fs.mjs
CHANGED
|
@@ -51,6 +51,13 @@ function getMenuPathname(opts, filePath) {
|
|
|
51
51
|
const result = normalizePathname(pathname, opts.basePathname);
|
|
52
52
|
return ensureSlash(result);
|
|
53
53
|
}
|
|
54
|
+
/** Normalize equivalent filesystem paths for string-key comparisons. */ function normalizePathKey(path) {
|
|
55
|
+
if (path.startsWith("\\\\?\\UNC\\")) path = `\\\\${path.slice(8)}`;
|
|
56
|
+
else if (path.startsWith("\\\\?\\")) path = path.slice(4);
|
|
57
|
+
else if (path.startsWith("//?/UNC/")) path = `//${path.slice(8)}`;
|
|
58
|
+
else if (path.startsWith("//?/")) path = path.slice(4);
|
|
59
|
+
return normalizePath(path).replace(/\\/g, "/");
|
|
60
|
+
}
|
|
54
61
|
/**
|
|
55
62
|
* Creates an id for the module, based on its path.
|
|
56
63
|
*
|
|
@@ -130,4 +137,4 @@ function getPathnameFromDirPath(opts, dirPath) {
|
|
|
130
137
|
if (pathname === "") return "/";
|
|
131
138
|
return pathname;
|
|
132
139
|
}
|
|
133
|
-
export { normalizePath as _, getPathnameFromDirPath as a,
|
|
140
|
+
export { normalizePath as _, getPathnameFromDirPath as a, parseRouteIndexName as b, isIndexModule as c, isMenuFileName as d, isModuleExt as f, isServiceWorkerName as g, isPluginModule as h, getMenuPathname as i, isLayoutModule as l, isPageModuleExt as m, errorBoundaryName as n, isEntryName as o, isPageExt as p, getExtension as r, isErrorName as s, createFileId as t, isMarkdownExt as u, normalizePathKey as v, removeExtension as x, normalizePathSlash as y };
|
package/lib/chunks/head.qwik.mjs
CHANGED
|
@@ -208,24 +208,12 @@ function getRouteLoaderCtx(requestEv) {
|
|
|
208
208
|
}
|
|
209
209
|
return ctx;
|
|
210
210
|
}
|
|
211
|
-
/**
|
|
212
|
-
* Update the loader paths store on client-side navigation.
|
|
213
|
-
*
|
|
214
|
-
* Only adds/updates entries for loaders present on the new route. Entries for loaders that are NOT
|
|
215
|
-
* on the new route are left untouched — their ComputedSignals keep their prior values, and no
|
|
216
|
-
* track() fires to invalidate them. If the user navigates back to a route where the loader IS
|
|
217
|
-
* present, the path updates and the signal re-fetches. This is the "stale is fine by default"
|
|
218
|
-
* contract: readers see old data until new data arrives.
|
|
219
|
-
*/ var updateRouteLoaderPaths = (ctx, loaderPaths, pageUrl) => {
|
|
211
|
+
/** Update route loader matching state on navigation. */ var updateRouteLoaderPaths = (ctx, loaderPaths, pageUrl) => {
|
|
220
212
|
if (!isServer) {
|
|
221
213
|
ctx.pagePathname = pageUrl.pathname;
|
|
222
214
|
ctx.pageSearch = pageUrl.search;
|
|
223
|
-
|
|
224
|
-
}
|
|
225
|
-
if (loaderPaths) for (const key in loaderPaths) {
|
|
226
|
-
ctx.loaderPaths[key] = loaderPaths[key];
|
|
227
|
-
if (!isServer && isDev) ctx.devRouteLoaderPaths[key] = true;
|
|
228
|
-
}
|
|
215
|
+
ctx.routeLoaderCandidates = loaderPaths;
|
|
216
|
+
} else if (loaderPaths) for (const key in loaderPaths) ctx.loaderPaths[key] = loaderPaths[key];
|
|
229
217
|
};
|
|
230
218
|
var getModuleRouteLoaders = (mods) => {
|
|
231
219
|
const routeLoaders = [];
|
|
@@ -262,6 +250,11 @@ var isImmutableLoader = (loaderId) => immutableLoaderIds.has(loaderId);
|
|
|
262
250
|
*/ var invalidateNavRouteLoaders = (state) => {
|
|
263
251
|
for (const id in state) if (!id.startsWith(ROUTE_LOADER_VALUE_PREFIX) && !immutableLoaderIds.has(id)) state[id].invalidate();
|
|
264
252
|
};
|
|
253
|
+
var applyClientRouteLoaderPath = (loaderId, ctx) => {
|
|
254
|
+
const currentPath = ctx.routeLoaderCandidates?.[loaderId];
|
|
255
|
+
if (currentPath) ctx.loaderPaths[loaderId] = currentPath;
|
|
256
|
+
else if (isDev && ctx.pagePathname) ctx.loaderPaths[loaderId] = ctx.pagePathname;
|
|
257
|
+
};
|
|
265
258
|
/**
|
|
266
259
|
* Inject a pre-loaded value into a ComputedSignal while preserving subscriptions. Delegates to the
|
|
267
260
|
* core helper which calls `invalidate({__v})` + `$computeIfNeeded$()` so the compute function runs
|
|
@@ -304,7 +297,7 @@ var resolveRouteLoaderByHash = (routeLoaders, loaderId) => {
|
|
|
304
297
|
enumerable: true
|
|
305
298
|
},
|
|
306
299
|
params: {
|
|
307
|
-
value:
|
|
300
|
+
value: rootRequestEv.params,
|
|
308
301
|
enumerable: true
|
|
309
302
|
},
|
|
310
303
|
pathname: {
|
|
@@ -518,20 +511,14 @@ var createRouteLoaderSignal = (loader, routeLoaderCtx, state) => {
|
|
|
518
511
|
return signal;
|
|
519
512
|
};
|
|
520
513
|
var ensureRouteLoaderSignal = (loader, state, routeLoaderCtx) => {
|
|
514
|
+
if (!isServer && routeLoaderCtx.pagePathname) applyClientRouteLoaderPath(loader.__id, routeLoaderCtx);
|
|
521
515
|
if (loader.__cacheControl === "immutable") immutableLoaderIds.add(loader.__id);
|
|
522
516
|
if (isServer && loader.__serializationStrategy === "never") state[getRouteLoaderValueStateKey(loader.__id)] = _UNINITIALIZED;
|
|
523
517
|
return state[loader.__id] ||= createRouteLoaderSignal(loader, routeLoaderCtx, state);
|
|
524
518
|
};
|
|
525
519
|
var ensureRouteLoaderSignals = (mods, state, routeLoaderCtx) => {
|
|
526
520
|
const loaders = getModuleRouteLoaders(mods);
|
|
527
|
-
for (let i = 0; i < loaders.length; i++)
|
|
528
|
-
const loader = loaders[i];
|
|
529
|
-
if (isDev && !isServer) {
|
|
530
|
-
const devCtx = routeLoaderCtx;
|
|
531
|
-
if (devCtx.pagePathname && !devCtx.devRouteLoaderPaths?.[loader.__id]) devCtx.loaderPaths[loader.__id] = devCtx.pagePathname;
|
|
532
|
-
}
|
|
533
|
-
ensureRouteLoaderSignal(loader, state, routeLoaderCtx);
|
|
534
|
-
}
|
|
521
|
+
for (let i = 0; i < loaders.length; i++) ensureRouteLoaderSignal(loaders[i], state, routeLoaderCtx);
|
|
535
522
|
return loaders;
|
|
536
523
|
};
|
|
537
524
|
var loadRouteLoader = (loader, requestEv) => {
|
|
@@ -554,9 +541,7 @@ var loadRouteLoader = (loader, requestEv) => {
|
|
|
554
541
|
/** @internal */ var routeLoaderQrl = (loaderQrl, ...rest) => {
|
|
555
542
|
const { id, validators, serializationStrategy, cacheControl, eTag, cacheKey, search, blockSSR } = getLoaderOptions(rest);
|
|
556
543
|
function loader() {
|
|
557
|
-
const
|
|
558
|
-
let signal = state[loader.__id];
|
|
559
|
-
if (!signal) signal = ensureRouteLoaderSignal(loader, state, _resolveContextWithoutSequentialScope(RouteLoaderCtxContext));
|
|
544
|
+
const signal = ensureRouteLoaderSignal(loader, _resolveContextWithoutSequentialScope(RouteStateContext), _resolveContextWithoutSequentialScope(RouteLoaderCtxContext));
|
|
560
545
|
signal.promise();
|
|
561
546
|
return signal;
|
|
562
547
|
}
|
|
@@ -851,6 +851,19 @@ async function runValidators(requestEv, validators, data, devMode) {
|
|
|
851
851
|
requestEv.send(requestEv.status(), serialized);
|
|
852
852
|
};
|
|
853
853
|
}
|
|
854
|
+
var staticPaths = /* @__PURE__ */ new Set(["__QWIK_ROUTER_STATIC_PATHS_ARRAY__"]);
|
|
855
|
+
/**
|
|
856
|
+
* Decide whether a given request path is a static path, for optimizing file access.
|
|
857
|
+
*
|
|
858
|
+
* @internal
|
|
859
|
+
*/ function isStaticPath(method, url) {
|
|
860
|
+
method = method.toUpperCase();
|
|
861
|
+
if (method !== "GET" && method !== "HEAD") return false;
|
|
862
|
+
const p = url.pathname;
|
|
863
|
+
if (p.startsWith("/" + (globalThis.__QWIK_BUILD_DIR__ || "build") + "/")) return true;
|
|
864
|
+
if (p.startsWith("/" + (globalThis.__QWIK_ASSETS_DIR__ || "assets") + "/")) return true;
|
|
865
|
+
return staticPaths.has(p);
|
|
866
|
+
}
|
|
854
867
|
/**
|
|
855
868
|
* Hypertext Transfer Protocol (HTTP) response status codes.
|
|
856
869
|
*
|
|
@@ -1167,7 +1180,7 @@ function createResolveRequestHandlers() {
|
|
|
1167
1180
|
if (isPageRoute) {
|
|
1168
1181
|
requestHandlers.push(loaderHandler(routeLoaders, route.$loaderPaths$));
|
|
1169
1182
|
requestHandlers.push(actionHandler(routeActions));
|
|
1170
|
-
|
|
1183
|
+
requestHandlers.push(route.$notFound$ ? fixStaticTrailingSlash : fixTrailingSlash);
|
|
1171
1184
|
}
|
|
1172
1185
|
if (isPageRoute) {
|
|
1173
1186
|
requestHandlers.push((ev) => {
|
|
@@ -1449,6 +1462,15 @@ function createResolveRequestHandlers() {
|
|
|
1449
1462
|
} else if (pathname.endsWith("/")) throw ev.redirect(HttpStatus.MovedPermanently, pathname.slice(0, pathname.length - 1) + search);
|
|
1450
1463
|
}
|
|
1451
1464
|
}
|
|
1465
|
+
/**
|
|
1466
|
+
* Prerendered pages are pruned from the production server route plan, so a request missing the
|
|
1467
|
+
* canonical trailing slash lands here as not found. Redirect it when the canonical path was
|
|
1468
|
+
* prerendered, and leave a genuine 404 alone.
|
|
1469
|
+
*/ function fixStaticTrailingSlash(ev) {
|
|
1470
|
+
const canonicalUrl = new URL(ev.originalUrl);
|
|
1471
|
+
canonicalUrl.pathname = globalThis.__NO_TRAILING_SLASH__ ? canonicalUrl.pathname.replace(/\/$/, "") : ensureSlash(canonicalUrl.pathname);
|
|
1472
|
+
if (isStaticPath(ev.request.method, canonicalUrl)) fixTrailingSlash(ev);
|
|
1473
|
+
}
|
|
1452
1474
|
function verifySerializable(data, qrl) {
|
|
1453
1475
|
try {
|
|
1454
1476
|
_verifySerializable(data, void 0);
|
|
@@ -1567,6 +1589,7 @@ The request origin "${inputOrigin}" does not match the server origin "${origin}"
|
|
|
1567
1589
|
actionsMiddleware,
|
|
1568
1590
|
checkBrand,
|
|
1569
1591
|
checkCSRF,
|
|
1592
|
+
fixStaticTrailingSlash,
|
|
1570
1593
|
fixTrailingSlash,
|
|
1571
1594
|
getPathname,
|
|
1572
1595
|
isLastModulePageRoute,
|
|
@@ -1579,7 +1602,7 @@ The request origin "${inputOrigin}" does not match the server origin "${origin}"
|
|
|
1579
1602
|
verifySerializable
|
|
1580
1603
|
};
|
|
1581
1604
|
}
|
|
1582
|
-
var { actionsMiddleware, checkBrand, checkCSRF, fixTrailingSlash, getPathname, isLastModulePageRoute, isQrl, loadersMiddleware, measure, renderQwikMiddleware, resolveRequestHandlers, streamServerFunctionResult, verifySerializable } = createResolveRequestHandlers();
|
|
1605
|
+
var { actionsMiddleware, checkBrand, checkCSRF, fixStaticTrailingSlash, fixTrailingSlash, getPathname, isLastModulePageRoute, isQrl, loadersMiddleware, measure, renderQwikMiddleware, resolveRequestHandlers, streamServerFunctionResult, verifySerializable } = createResolveRequestHandlers();
|
|
1583
1606
|
/** @public */ var ESCAPE_HTML = /[&<>]/g;
|
|
1584
1607
|
var escapeHtml = (s) => {
|
|
1585
1608
|
return s.replace(ESCAPE_HTML, (c) => {
|
|
@@ -1704,4 +1727,4 @@ function runQwikRouter(serverRequestEv, loadedRoute, requestHandlers, rebuildRou
|
|
|
1704
1727
|
};
|
|
1705
1728
|
}
|
|
1706
1729
|
}
|
|
1707
|
-
export {
|
|
1730
|
+
export { isStaticPath as a, RewriteMessage as c, resolveRequestHandlers as i, mergeHeadersCookies as l, getErrorHtml as n, clearLoaderCache as o, renderQwikMiddleware as r, clearSsrCache as s, runQwikRouter as t };
|
package/lib/index.d.ts
CHANGED
|
@@ -1062,6 +1062,7 @@ declare type RouteLoaderCtx = {
|
|
|
1062
1062
|
goto?: NoSerialize<RouteNavigate>;
|
|
1063
1063
|
/** Client manifest hash for q-loader fetch URLs. */
|
|
1064
1064
|
manifestHash?: string;
|
|
1065
|
+
routeLoaderCandidates?: Record<string, string>;
|
|
1065
1066
|
};
|
|
1066
1067
|
|
|
1067
1068
|
/* Excluded from this release type: routeLoaderQrl */
|
|
@@ -1316,16 +1317,16 @@ export declare const zod$: ZodConstructor;
|
|
|
1316
1317
|
export declare type ZodConstructor = {
|
|
1317
1318
|
<T extends z_2.ZodRawShape>(schema: T): ZodDataValidator<z_2.ZodObject<T>>;
|
|
1318
1319
|
<T extends z_2.ZodRawShape>(schema: (zod: typeof z_2.z, ev: RequestEvent) => T): ZodDataValidator<z_2.ZodObject<T>>;
|
|
1319
|
-
<T extends z_2.
|
|
1320
|
-
<T extends z_2.
|
|
1320
|
+
<T extends z_2.ZodType>(schema: T): ZodDataValidator<T>;
|
|
1321
|
+
<T extends z_2.ZodType>(schema: (zod: typeof z_2.z, ev: RequestEvent) => T): ZodDataValidator<T>;
|
|
1321
1322
|
};
|
|
1322
1323
|
|
|
1323
1324
|
/** @public */
|
|
1324
1325
|
declare type ZodConstructorQRL = {
|
|
1325
1326
|
<T extends z_2.ZodRawShape>(schema: QRL<T>): ZodDataValidator<z_2.ZodObject<T>>;
|
|
1326
1327
|
<T extends z_2.ZodRawShape>(schema: QRL<(zod: typeof z_2.z, ev: RequestEvent) => T>): ZodDataValidator<z_2.ZodObject<T>>;
|
|
1327
|
-
<T extends z_2.
|
|
1328
|
-
<T extends z_2.
|
|
1328
|
+
<T extends z_2.ZodType>(schema: QRL<T>): ZodDataValidator<T>;
|
|
1329
|
+
<T extends z_2.ZodType>(schema: QRL<(zod: typeof z_2.z, ev: RequestEvent) => T>): ZodDataValidator<T>;
|
|
1329
1330
|
};
|
|
1330
1331
|
|
|
1331
1332
|
/** @public */
|
package/lib/index.qwik.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as ensureSlash } from "./chunks/pathname.mjs";
|
|
2
|
-
import { A as routeLoader$, B as RouteLoaderCtxContext, E as isImmutableLoader, F as ContentContext, G as QACTION_KEY, H as RouteNavigateContext, I as ContentInternalContext, J as Q_ROUTE, K as QDATA_KEY, L as DocumentHeadContext, M as setLoaderSignalValue, P as updateRouteLoaderPaths, R as HttpStatusContext, T as invalidateNavRouteLoaders, U as RoutePreventNavigateContext, V as RouteLocationContext, W as RouteStateContext, _ as fetchRouteLoaderData, b as getRequestEvent, c as shouldPreload, d as loadRoute, g as ensureRouteLoaderSignals, i as getClientNavPath, j as routeLoaderQrl, l as toPath, m as clearNavFetchCache, n as resolveHead, o as isSameOrigin, q as QFN_KEY, s as isSamePath, t as createDocumentHead, u as toUrl, y as getModuleRouteLoaders, z as RouteActionContext } from "./chunks/head.qwik.mjs";
|
|
2
|
+
import { A as routeLoader$, B as RouteLoaderCtxContext, E as isImmutableLoader, F as ContentContext, G as QACTION_KEY, H as RouteNavigateContext, I as ContentInternalContext, J as Q_ROUTE, K as QDATA_KEY, L as DocumentHeadContext, M as setLoaderSignalValue, P as updateRouteLoaderPaths, R as HttpStatusContext, T as invalidateNavRouteLoaders, U as RoutePreventNavigateContext, V as RouteLocationContext, W as RouteStateContext, _ as fetchRouteLoaderData, a as isPromise, b as getRequestEvent, c as shouldPreload, d as loadRoute, g as ensureRouteLoaderSignals, i as getClientNavPath, j as routeLoaderQrl, l as toPath, m as clearNavFetchCache, n as resolveHead, o as isSameOrigin, q as QFN_KEY, s as isSamePath, t as createDocumentHead, u as toUrl, y as getModuleRouteLoaders, z as RouteActionContext } from "./chunks/head.qwik.mjs";
|
|
3
3
|
import { SkipRender, Slot, _captures, _fnSignal, _getConstProps, _getVarProps, _jsxSorted, _jsxSplit, _qrlSync, _restProps, _wrapProp, componentQrl, createComputedQrl, createElement, eventQrl, getLocale, implicit$FirstArg, inlinedQrl, isBrowser, isDev, isServer, noSerialize, untrack, useContext, useContextProvider, useErrorBoundary, useOnWindow, useServerData, useSignal, useStore, useTaskQrl, useVisibleTaskQrl, withLocale } from "@qwik.dev/core";
|
|
4
4
|
import { Fragment } from "@qwik.dev/core/jsx-runtime";
|
|
5
5
|
import * as qwikRouterConfig from "@qwik-router-config";
|
|
@@ -1026,7 +1026,14 @@ function initializeSPA(goto, scroller) {
|
|
|
1026
1026
|
const contentModules = track(contentInternal);
|
|
1027
1027
|
if (!contentModules) return;
|
|
1028
1028
|
const actionData = track(actionDataSignal);
|
|
1029
|
-
|
|
1029
|
+
let head;
|
|
1030
|
+
try {
|
|
1031
|
+
head = track(() => resolveHead(actionData, loaderState, routeLocation, contentModules, getLocale(""), serverHead));
|
|
1032
|
+
} catch (error) {
|
|
1033
|
+
if (isServer || isPromise(error)) throw error;
|
|
1034
|
+
console.error(error);
|
|
1035
|
+
return;
|
|
1036
|
+
}
|
|
1030
1037
|
documentHead.links = head.links;
|
|
1031
1038
|
documentHead.meta = head.meta;
|
|
1032
1039
|
documentHead.styles = head.styles;
|
|
@@ -1220,7 +1227,7 @@ var flattenZodIssues = (issues) => {
|
|
|
1220
1227
|
async validate(ev, inputData) {
|
|
1221
1228
|
const schema = await qrl.resolve().then((obj) => {
|
|
1222
1229
|
if (typeof obj === "function") obj = obj(z$1, ev);
|
|
1223
|
-
if (obj instanceof z$1.
|
|
1230
|
+
if (obj instanceof z$1.ZodType) return obj;
|
|
1224
1231
|
else return z$1.object(obj);
|
|
1225
1232
|
});
|
|
1226
1233
|
const data = inputData ?? await ev.parseBody();
|
|
@@ -28,11 +28,16 @@ import { _TextEncoderStream_polyfill, getErrorHtml, isStaticPath, mergeHeadersCo
|
|
|
28
28
|
return env[key];
|
|
29
29
|
} },
|
|
30
30
|
getWritableStream: (status, headers, cookies, resolve) => {
|
|
31
|
-
const
|
|
32
|
-
resolve(new Response(readable, {
|
|
31
|
+
const responseInit = {
|
|
33
32
|
status,
|
|
34
33
|
headers: mergeHeadersCookies(headers, cookies)
|
|
35
|
-
}
|
|
34
|
+
};
|
|
35
|
+
if (status === 204 || status === 205 || status === 304) {
|
|
36
|
+
resolve(new Response(null, responseInit));
|
|
37
|
+
return new WritableStream();
|
|
38
|
+
}
|
|
39
|
+
const { readable, writable } = new TransformStream();
|
|
40
|
+
resolve(new Response(readable, responseInit));
|
|
36
41
|
return writable;
|
|
37
42
|
},
|
|
38
43
|
getClientConn: () => {
|
|
@@ -2,7 +2,7 @@ import { Y as _asyncRequestStore, d as loadRoute } from "../../chunks/head.qwik.
|
|
|
2
2
|
import { c as resolveValidInternalFullPathname, l as trimInternalPathname, s as recognizeRequest, u as trimRecognizedInternalPathname } from "../../chunks/request-path.mjs";
|
|
3
3
|
import { i as RedirectMessage, r as AbortMessage, t as ServerError } from "../../chunks/server-error.mjs";
|
|
4
4
|
import { t as devPreloadedRouteLoaders } from "../../chunks/dev-preloaded-route-loader.mjs";
|
|
5
|
-
import { a as
|
|
5
|
+
import { a as isStaticPath, c as RewriteMessage, i as resolveRequestHandlers, l as mergeHeadersCookies, n as getErrorHtml, o as clearLoaderCache, r as renderQwikMiddleware, s as clearSsrCache, t as runQwikRouter } from "../../chunks/user-response.mjs";
|
|
6
6
|
import { isDev } from "@qwik.dev/core";
|
|
7
7
|
var qwikRouterConfig;
|
|
8
8
|
async function getConfig() {
|
|
@@ -46,18 +46,6 @@ async function loadRequestHandlers(qwikRouterConfig, pathname, method, checkOrig
|
|
|
46
46
|
};
|
|
47
47
|
return runQwikRouter(serverRequestEv, loadedRoute, requestHandlers, rebuildRouteInfo, config.basePathname);
|
|
48
48
|
}
|
|
49
|
-
var staticPaths = /* @__PURE__ */ new Set(["__QWIK_ROUTER_STATIC_PATHS_ARRAY__"]);
|
|
50
|
-
/**
|
|
51
|
-
* Decide whether a given request path is a static path, for optimizing file access.
|
|
52
|
-
*
|
|
53
|
-
* @internal
|
|
54
|
-
*/ function isStaticPath(method, url) {
|
|
55
|
-
if (method.toUpperCase() !== "GET") return false;
|
|
56
|
-
const p = url.pathname;
|
|
57
|
-
if (p.startsWith("/" + (globalThis.__QWIK_BUILD_DIR__ || "build") + "/")) return true;
|
|
58
|
-
if (p.startsWith("/" + (globalThis.__QWIK_ASSETS_DIR__ || "assets") + "/")) return true;
|
|
59
|
-
return staticPaths.has(p);
|
|
60
|
-
}
|
|
61
49
|
/**
|
|
62
50
|
* TextEncoderStream polyfill based on Node.js' implementation
|
|
63
51
|
* https://github.com/nodejs/node/blob/3f3226c8e363a5f06c1e6a37abd59b6b8c1923f1/lib/internal/webstreams/encoding.js#L38-L119
|
package/lib/vite/index.mjs
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { r as isSameOriginUrl, t as ensureSlash } from "../chunks/pathname.mjs";
|
|
2
2
|
import { c as resolveValidInternalFullPathname, s as recognizeRequest, u as trimRecognizedInternalPathname } from "../chunks/request-path.mjs";
|
|
3
3
|
import { n as addWarning, t as addError } from "../chunks/format.mjs";
|
|
4
|
-
import { _ as normalizePath$1, a as getPathnameFromDirPath, b as
|
|
4
|
+
import { _ as normalizePath$1, a as getPathnameFromDirPath, b as parseRouteIndexName, c as isIndexModule, d as isMenuFileName, f as isModuleExt, g as isServiceWorkerName, h as isPluginModule, i as getMenuPathname, l as isLayoutModule, m as isPageModuleExt, n as errorBoundaryName, o as isEntryName, p as isPageExt, r as getExtension, s as isErrorName, t as createFileId, u as isMarkdownExt, v as normalizePathKey, x as removeExtension } from "../chunks/fs.mjs";
|
|
5
5
|
import { t as devPreloadedRouteLoaders } from "../chunks/dev-preloaded-route-loader.mjs";
|
|
6
6
|
import { t as createRouteTester } from "../chunks/routes.mjs";
|
|
7
7
|
import fs, { existsSync } from "node:fs";
|
|
8
8
|
import path, { basename, dirname, extname, isAbsolute, join, resolve } from "node:path";
|
|
9
9
|
import { readFile } from "node:fs/promises";
|
|
10
10
|
import { loadEnv, mergeConfig, normalizePath } from "vite";
|
|
11
|
-
import { findExports, findStaticImports } from "mlly";
|
|
11
|
+
import { findExports, findStaticImports, parseStaticImport } from "mlly";
|
|
12
12
|
import { marked } from "marked";
|
|
13
13
|
import { createHash } from "node:crypto";
|
|
14
14
|
import { SourceMapGenerator } from "source-map";
|
|
@@ -1093,7 +1093,7 @@ function getClientRouteBundleNames(qwikPlugin, r) {
|
|
|
1093
1093
|
if (loadersByFile) {
|
|
1094
1094
|
const nodeLoaderHashes = [];
|
|
1095
1095
|
for (const filePath of routeLoaderFiles) {
|
|
1096
|
-
const hashes = loadersByFile.get(filePath);
|
|
1096
|
+
const hashes = loadersByFile.get(normalizePathKey(filePath));
|
|
1097
1097
|
if (hashes) nodeLoaderHashes.push(...hashes);
|
|
1098
1098
|
}
|
|
1099
1099
|
if (nodeLoaderHashes.length > 0) lines.push(`${nextIndent}_R: ${JSON.stringify(nodeLoaderHashes)},`);
|
|
@@ -2083,10 +2083,10 @@ var QWIK_ROUTER_SW_REGISTER = "@qwik-router-sw-register";
|
|
|
2083
2083
|
var VIRTUAL_SERVER_FNS = "virtual:qwik-router-server-fns";
|
|
2084
2084
|
/** Replace or strip `_R: "__LOADERS:path1|path2__"` placeholders in a bundle chunk. */ function replaceLoaderPlaceholders(code, loadersByFile) {
|
|
2085
2085
|
return code.replace(/_R\s*:\s*(["'`])__LOADERS:([^"'`]+)__\1\s*,?/g, (_match, _q, paths) => {
|
|
2086
|
-
const filePaths = paths.split("|");
|
|
2086
|
+
const filePaths = JSON.parse(`"${paths}"`).split("|");
|
|
2087
2087
|
const hashes = [];
|
|
2088
2088
|
for (const filePath of filePaths) {
|
|
2089
|
-
const fileHashes = loadersByFile.get(filePath);
|
|
2089
|
+
const fileHashes = loadersByFile.get(normalizePathKey(filePath));
|
|
2090
2090
|
if (fileHashes) hashes.push(...fileHashes);
|
|
2091
2091
|
}
|
|
2092
2092
|
if (hashes.length > 0) return `_R: ${JSON.stringify(hashes)},`;
|
|
@@ -2094,7 +2094,7 @@ var VIRTUAL_SERVER_FNS = "virtual:qwik-router-server-fns";
|
|
|
2094
2094
|
});
|
|
2095
2095
|
}
|
|
2096
2096
|
function addRouteLoaderHash(loadersByFile, filePath, hash) {
|
|
2097
|
-
const normalizedPath =
|
|
2097
|
+
const normalizedPath = normalizePathKey(filePath).split(/[?#]/, 1)[0];
|
|
2098
2098
|
const existing = loadersByFile.get(normalizedPath);
|
|
2099
2099
|
if (!existing) {
|
|
2100
2100
|
loadersByFile.set(normalizedPath, [hash]);
|
|
@@ -2107,7 +2107,7 @@ function addRouteLoaderHash(loadersByFile, filePath, hash) {
|
|
|
2107
2107
|
return false;
|
|
2108
2108
|
}
|
|
2109
2109
|
function clearRouteLoaderHashes(loadersByFile, filePath) {
|
|
2110
|
-
return loadersByFile.delete(
|
|
2110
|
+
return loadersByFile.delete(normalizePathKey(filePath).split(/[?#]/, 1)[0]);
|
|
2111
2111
|
}
|
|
2112
2112
|
function isRouterSourceFilePath(filePath) {
|
|
2113
2113
|
const fileName = basename(filePath);
|
|
@@ -2131,7 +2131,7 @@ function collectRouteLoaderOwners(node, owners) {
|
|
|
2131
2131
|
for (const file of node._files) if (file.type === "layout" || file.type === "route") owners.add(file.filePath);
|
|
2132
2132
|
for (const child of node.children.values()) collectRouteLoaderOwners(child, owners);
|
|
2133
2133
|
}
|
|
2134
|
-
async function
|
|
2134
|
+
async function collectRouteLoaderSources(owner, filePath, resolveSource, sources, seen = /* @__PURE__ */ new Set([owner])) {
|
|
2135
2135
|
let code, exportEntries;
|
|
2136
2136
|
try {
|
|
2137
2137
|
code = await readFile(filePath, "utf-8");
|
|
@@ -2140,26 +2140,38 @@ async function collectReExportSources(owner, filePath, resolveSource, sources, s
|
|
|
2140
2140
|
} catch {
|
|
2141
2141
|
return;
|
|
2142
2142
|
}
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
const
|
|
2146
|
-
if (
|
|
2143
|
+
const importedFactories = /* @__PURE__ */ new Map();
|
|
2144
|
+
for (const entry of findStaticImports(code)) {
|
|
2145
|
+
const parsed = parseStaticImport(entry);
|
|
2146
|
+
if (parsed.defaultImport) importedFactories.set(parsed.defaultImport, entry.specifier);
|
|
2147
|
+
if (parsed.namedImports) for (const localName of Object.values(parsed.namedImports)) importedFactories.set(localName, entry.specifier);
|
|
2148
|
+
}
|
|
2149
|
+
const specifiers = /* @__PURE__ */ new Set();
|
|
2150
|
+
for (const exp of exportEntries) if (exp.specifier) specifiers.add(exp.specifier);
|
|
2151
|
+
else if (/^export\s+(?:const|let|var)\s*{/.test(exp.code)) {
|
|
2152
|
+
const factoryName = code.slice(exp.end).match(/^\s*([\w$]+)(?:\s*<[^;()]*>)?\s*\(/)?.[1];
|
|
2153
|
+
const specifier = factoryName && importedFactories.get(factoryName);
|
|
2154
|
+
if (specifier) specifiers.add(specifier);
|
|
2155
|
+
}
|
|
2156
|
+
for (const specifier of specifiers) {
|
|
2157
|
+
const resolved = await resolveSource(specifier, filePath);
|
|
2158
|
+
if (!resolved || resolved.charCodeAt(0) === 0) continue;
|
|
2147
2159
|
const resolvedPath = normalizePath$1(resolved.split(/[?#]/, 1)[0]);
|
|
2148
2160
|
let ownerSources = sources.get(owner);
|
|
2149
2161
|
if (!ownerSources) sources.set(owner, ownerSources = []);
|
|
2150
2162
|
if (!ownerSources.includes(resolvedPath)) ownerSources.push(resolvedPath);
|
|
2151
2163
|
if (!seen.has(resolvedPath)) {
|
|
2152
2164
|
seen.add(resolvedPath);
|
|
2153
|
-
await
|
|
2165
|
+
await collectRouteLoaderSources(owner, resolvedPath, resolveSource, sources, seen);
|
|
2154
2166
|
}
|
|
2155
|
-
}
|
|
2167
|
+
}
|
|
2156
2168
|
}
|
|
2157
2169
|
async function findRouteLoaderSourceFiles(ctx, resolveSource) {
|
|
2158
2170
|
const sources = /* @__PURE__ */ new Map();
|
|
2159
2171
|
const owners = /* @__PURE__ */ new Set();
|
|
2160
2172
|
collectRouteLoaderOwners(ctx.routeTrie, owners);
|
|
2161
2173
|
for (const plugin of ctx.serverPlugins) owners.add(plugin.filePath);
|
|
2162
|
-
await Promise.all([...owners].map((owner) =>
|
|
2174
|
+
await Promise.all([...owners].map((owner) => collectRouteLoaderSources(owner, owner, resolveSource, sources)));
|
|
2163
2175
|
return sources;
|
|
2164
2176
|
}
|
|
2165
2177
|
function invalidateRouterConfigModules(server) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qwik.dev/router",
|
|
3
3
|
"description": "The router for Qwik.",
|
|
4
|
-
"version": "2.0.0-beta.
|
|
4
|
+
"version": "2.0.0-beta.41",
|
|
5
5
|
"bugs": "https://github.com/QwikDev/qwik/issues",
|
|
6
6
|
"dependencies": {
|
|
7
7
|
"@azure/functions": "3.5.1",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"typescript": "5.9.3",
|
|
42
42
|
"uvu": "0.5.6",
|
|
43
43
|
"vite": "8.2.1",
|
|
44
|
-
"@qwik.dev/core": "2.0.0-beta.
|
|
44
|
+
"@qwik.dev/core": "2.0.0-beta.41"
|
|
45
45
|
},
|
|
46
46
|
"engines": {
|
|
47
47
|
"node": "^18.17.0 || ^20.3.0 || >=21.0.0"
|
|
@@ -147,10 +147,6 @@
|
|
|
147
147
|
"types": "./lib/vite/index.d.ts",
|
|
148
148
|
"import": "./lib/vite/index.mjs"
|
|
149
149
|
},
|
|
150
|
-
"./service-worker": {
|
|
151
|
-
"types": "./service-worker.d.ts",
|
|
152
|
-
"import": "./lib/service-worker.mjs"
|
|
153
|
-
},
|
|
154
150
|
"./package.json": "./package.json"
|
|
155
151
|
},
|
|
156
152
|
"files": [
|
|
@@ -170,7 +166,7 @@
|
|
|
170
166
|
"main": "./lib/index.qwik.mjs",
|
|
171
167
|
"peerDependencies": {
|
|
172
168
|
"vite": ">=8 <9",
|
|
173
|
-
"@qwik.dev/core": "
|
|
169
|
+
"@qwik.dev/core": "2.0.0-beta.41"
|
|
174
170
|
},
|
|
175
171
|
"publishConfig": {
|
|
176
172
|
"access": "public"
|