@pyreon/zero 0.13.1 → 0.15.0
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/api-routes-DANluJic.js +146 -0
- package/lib/client.js +3 -1
- package/lib/csp.js +19 -9
- package/lib/{fs-router-CQ7Zxeca.js → fs-router-ZebyutPa.js} +43 -6
- package/lib/image-plugin.js +4 -0
- package/lib/image.js +1 -50
- package/lib/index.js +1 -50
- package/lib/link.js +1 -49
- package/lib/script.js +1 -49
- package/lib/server.js +6 -688
- package/lib/theme.js +1 -50
- package/lib/types/i18n-routing.d.ts +4 -4
- package/lib/types/index.d.ts +23 -13
- package/lib/types/link.d.ts +3 -3
- package/lib/types/server.d.ts +28 -5
- package/lib/types/theme.d.ts +2 -2
- package/lib/vite-plugin-E4BHYvYW.js +855 -0
- package/package.json +15 -13
- package/src/app.ts +21 -1
- package/src/csp.ts +28 -12
- package/src/fs-router.ts +53 -3
- package/src/ssg-plugin.ts +366 -0
- package/src/types.ts +28 -9
- package/src/vite-plugin.ts +220 -40
- package/lib/actions.js.map +0 -1
- package/lib/ai.js.map +0 -1
- package/lib/api-routes.js.map +0 -1
- package/lib/cache.js.map +0 -1
- package/lib/client.js.map +0 -1
- package/lib/compression.js.map +0 -1
- package/lib/config.js.map +0 -1
- package/lib/cors.js.map +0 -1
- package/lib/csp.js.map +0 -1
- package/lib/env.js.map +0 -1
- package/lib/favicon.js.map +0 -1
- package/lib/font.js.map +0 -1
- package/lib/fs-router-3xzp-4Wj.js.map +0 -1
- package/lib/fs-router-CQ7Zxeca.js.map +0 -1
- package/lib/i18n-routing.js.map +0 -1
- package/lib/image-plugin.js.map +0 -1
- package/lib/image.js.map +0 -1
- package/lib/index.js.map +0 -1
- package/lib/link.js.map +0 -1
- package/lib/logger.js.map +0 -1
- package/lib/meta.js.map +0 -1
- package/lib/middleware.js.map +0 -1
- package/lib/og-image.js.map +0 -1
- package/lib/rate-limit.js.map +0 -1
- package/lib/script.js.map +0 -1
- package/lib/seo.js.map +0 -1
- package/lib/server.js.map +0 -1
- package/lib/testing.js.map +0 -1
- package/lib/theme.js.map +0 -1
- package/lib/types/actions.d.ts.map +0 -1
- package/lib/types/ai.d.ts.map +0 -1
- package/lib/types/api-routes.d.ts.map +0 -1
- package/lib/types/cache.d.ts.map +0 -1
- package/lib/types/client.d.ts.map +0 -1
- package/lib/types/compression.d.ts.map +0 -1
- package/lib/types/config.d.ts.map +0 -1
- package/lib/types/cors.d.ts.map +0 -1
- package/lib/types/csp.d.ts.map +0 -1
- package/lib/types/env.d.ts.map +0 -1
- package/lib/types/favicon.d.ts.map +0 -1
- package/lib/types/font.d.ts.map +0 -1
- package/lib/types/i18n-routing.d.ts.map +0 -1
- package/lib/types/image-plugin.d.ts.map +0 -1
- package/lib/types/image.d.ts.map +0 -1
- package/lib/types/index.d.ts.map +0 -1
- package/lib/types/link.d.ts.map +0 -1
- package/lib/types/logger.d.ts.map +0 -1
- package/lib/types/meta.d.ts.map +0 -1
- package/lib/types/middleware.d.ts.map +0 -1
- package/lib/types/og-image.d.ts.map +0 -1
- package/lib/types/rate-limit.d.ts.map +0 -1
- package/lib/types/script.d.ts.map +0 -1
- package/lib/types/seo.d.ts.map +0 -1
- package/lib/types/server.d.ts.map +0 -1
- package/lib/types/testing.d.ts.map +0 -1
- package/lib/types/theme.d.ts.map +0 -1
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { l as __exportAll } from "./fs-router-ZebyutPa.js";
|
|
2
|
+
|
|
3
|
+
//#region src/api-routes.ts
|
|
4
|
+
var api_routes_exports = /* @__PURE__ */ __exportAll({
|
|
5
|
+
apiFilePathToPattern: () => apiFilePathToPattern,
|
|
6
|
+
createApiMiddleware: () => createApiMiddleware,
|
|
7
|
+
generateApiRouteModule: () => generateApiRouteModule,
|
|
8
|
+
isApiRoute: () => isApiRoute,
|
|
9
|
+
matchApiRoute: () => matchApiRoute
|
|
10
|
+
});
|
|
11
|
+
/**
|
|
12
|
+
* Match a URL path against an API route pattern.
|
|
13
|
+
* Returns extracted params or null if no match.
|
|
14
|
+
*/
|
|
15
|
+
function matchApiRoute(pattern, path) {
|
|
16
|
+
const patternParts = pattern.split("/").filter(Boolean);
|
|
17
|
+
const pathParts = path.split("/").filter(Boolean);
|
|
18
|
+
const params = {};
|
|
19
|
+
for (let i = 0; i < patternParts.length; i++) {
|
|
20
|
+
const pp = patternParts[i];
|
|
21
|
+
if (!pp) continue;
|
|
22
|
+
if (pp.endsWith("*")) {
|
|
23
|
+
const paramName = pp.slice(1, -1);
|
|
24
|
+
params[paramName] = pathParts.slice(i).join("/");
|
|
25
|
+
return params;
|
|
26
|
+
}
|
|
27
|
+
if (i >= pathParts.length) return null;
|
|
28
|
+
if (pp.startsWith(":")) {
|
|
29
|
+
params[pp.slice(1)] = pathParts[i];
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
if (pp !== pathParts[i]) return null;
|
|
33
|
+
}
|
|
34
|
+
return patternParts.length === pathParts.length ? params : null;
|
|
35
|
+
}
|
|
36
|
+
const HTTP_METHODS = [
|
|
37
|
+
"GET",
|
|
38
|
+
"POST",
|
|
39
|
+
"PUT",
|
|
40
|
+
"PATCH",
|
|
41
|
+
"DELETE",
|
|
42
|
+
"HEAD",
|
|
43
|
+
"OPTIONS"
|
|
44
|
+
];
|
|
45
|
+
/**
|
|
46
|
+
* Create a middleware that dispatches API route requests.
|
|
47
|
+
* API routes are matched by URL pattern and HTTP method.
|
|
48
|
+
*/
|
|
49
|
+
function createApiMiddleware(routes) {
|
|
50
|
+
return async (ctx) => {
|
|
51
|
+
for (const route of routes) {
|
|
52
|
+
const params = matchApiRoute(route.pattern, ctx.path);
|
|
53
|
+
if (!params) continue;
|
|
54
|
+
const method = ctx.req.method.toUpperCase();
|
|
55
|
+
const handler = route.module[method];
|
|
56
|
+
if (!handler) {
|
|
57
|
+
const allowed = HTTP_METHODS.filter((m) => route.module[m]).join(", ");
|
|
58
|
+
return new Response(null, {
|
|
59
|
+
status: 405,
|
|
60
|
+
headers: {
|
|
61
|
+
Allow: allowed,
|
|
62
|
+
"Content-Type": "application/json"
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
return handler({
|
|
67
|
+
request: ctx.req,
|
|
68
|
+
url: ctx.url,
|
|
69
|
+
path: ctx.path,
|
|
70
|
+
params,
|
|
71
|
+
headers: ctx.req.headers
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Detect whether a route file is an API route.
|
|
78
|
+
* API routes are `.ts` or `.js` files inside an `api/` directory.
|
|
79
|
+
*/
|
|
80
|
+
function isApiRoute(filePath) {
|
|
81
|
+
const normalized = filePath.replace(/\\/g, "/");
|
|
82
|
+
return normalized.startsWith("api/") && (normalized.endsWith(".ts") || normalized.endsWith(".js")) && !normalized.endsWith(".tsx") && !normalized.endsWith(".jsx");
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Convert an API route file path to a URL pattern.
|
|
86
|
+
*
|
|
87
|
+
* Examples:
|
|
88
|
+
* "api/posts.ts" → "/api/posts"
|
|
89
|
+
* "api/posts/index.ts" → "/api/posts"
|
|
90
|
+
* "api/posts/[id].ts" → "/api/posts/:id"
|
|
91
|
+
* "api/[...path].ts" → "/api/:path*"
|
|
92
|
+
*/
|
|
93
|
+
function apiFilePathToPattern(filePath) {
|
|
94
|
+
let route = filePath;
|
|
95
|
+
for (const ext of [".ts", ".js"]) if (route.endsWith(ext)) {
|
|
96
|
+
route = route.slice(0, -ext.length);
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
const segments = route.split("/");
|
|
100
|
+
const urlSegments = [];
|
|
101
|
+
for (const seg of segments) {
|
|
102
|
+
if (seg === "index") continue;
|
|
103
|
+
const catchAll = seg.match(/^\[\.\.\.(\w+)\]$/);
|
|
104
|
+
if (catchAll) {
|
|
105
|
+
urlSegments.push(`:${catchAll[1]}*`);
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
const dynamic = seg.match(/^\[(\w+)\]$/);
|
|
109
|
+
if (dynamic) {
|
|
110
|
+
urlSegments.push(`:${dynamic[1]}`);
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
urlSegments.push(seg);
|
|
114
|
+
}
|
|
115
|
+
return `/${urlSegments.join("/")}`;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Generate a virtual module that exports API route entries.
|
|
119
|
+
* Each entry maps a URL pattern to a module with HTTP method handlers.
|
|
120
|
+
*/
|
|
121
|
+
function generateApiRouteModule(files, routesDir) {
|
|
122
|
+
const apiFiles = files.filter(isApiRoute);
|
|
123
|
+
if (apiFiles.length === 0) return "export const apiRoutes = []\n";
|
|
124
|
+
const imports = [];
|
|
125
|
+
const entries = [];
|
|
126
|
+
for (let i = 0; i < apiFiles.length; i++) {
|
|
127
|
+
const name = `_api${i}`;
|
|
128
|
+
const file = apiFiles[i];
|
|
129
|
+
if (!file) continue;
|
|
130
|
+
const fullPath = `${routesDir}/${file}`;
|
|
131
|
+
const pattern = apiFilePathToPattern(file);
|
|
132
|
+
imports.push(`import * as ${name} from "${fullPath}"`);
|
|
133
|
+
entries.push(` { pattern: ${JSON.stringify(pattern)}, module: ${name} }`);
|
|
134
|
+
}
|
|
135
|
+
return [
|
|
136
|
+
...imports,
|
|
137
|
+
"",
|
|
138
|
+
"export const apiRoutes = [",
|
|
139
|
+
entries.join(",\n"),
|
|
140
|
+
"]"
|
|
141
|
+
].join("\n");
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
//#endregion
|
|
145
|
+
export { matchApiRoute as i, createApiMiddleware as n, generateApiRouteModule as r, api_routes_exports as t };
|
|
146
|
+
//# sourceMappingURL=api-routes-DANluJic.js.map
|
package/lib/client.js
CHANGED
|
@@ -16,7 +16,9 @@ function createApp(options) {
|
|
|
16
16
|
...options.url ? { url: options.url } : {},
|
|
17
17
|
scrollBehavior: "top"
|
|
18
18
|
});
|
|
19
|
-
const
|
|
19
|
+
const hasLayoutInRoutes = options.layout !== void 0 && options.routes.some((r) => r.component === options.layout);
|
|
20
|
+
if (hasLayoutInRoutes && process.env.NODE_ENV !== "production") console.warn("[Pyreon] `createApp({ layout })` was passed a component that is ALSO a parent route in the matched chain (likely an fs-router `_layout.tsx`). The explicit `layout` option is being ignored to prevent double-mount. Remove the `layout` argument from `createApp`/`startClient` — the fs-router-emitted route handles it.");
|
|
21
|
+
const Layout = hasLayoutInRoutes ? DefaultLayout : options.layout ?? DefaultLayout;
|
|
20
22
|
function App() {
|
|
21
23
|
return h(HeadProvider, null, h(RouterProvider, { router }, h(Layout, null, h(RouterView, null))));
|
|
22
24
|
}
|
package/lib/csp.js
CHANGED
|
@@ -63,17 +63,27 @@ function buildCspHeader(directives, nonce) {
|
|
|
63
63
|
return parts.join("; ");
|
|
64
64
|
}
|
|
65
65
|
/**
|
|
66
|
-
* Generate a random nonce string (base64, 16 bytes).
|
|
66
|
+
* Generate a cryptographically-random nonce string (base64, 16 bytes).
|
|
67
|
+
*
|
|
68
|
+
* Throws when `crypto.getRandomValues` is unavailable. CSP nonces protect
|
|
69
|
+
* against XSS by gating inline script execution; a predictable nonce
|
|
70
|
+
* (`Math.random` ~31 bits of entropy) bypasses CSP entirely. Silent
|
|
71
|
+
* degradation here was a security anti-pattern — we surface the
|
|
72
|
+
* misconfiguration loudly instead.
|
|
73
|
+
*
|
|
74
|
+
* Realistic deployments always have `crypto.getRandomValues`: Node 18+,
|
|
75
|
+
* Bun, Deno, browsers, edge workers (Cloudflare/Vercel/Netlify), and
|
|
76
|
+
* vitest/happy-dom all expose it via `globalThis.crypto`. If you hit
|
|
77
|
+
* this throw, your environment is unusual — fix the env, don't downgrade
|
|
78
|
+
* the security primitive.
|
|
67
79
|
*/
|
|
68
80
|
function generateNonce() {
|
|
69
|
-
if (typeof crypto
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
76
|
-
return Math.random().toString(36).slice(2) + Math.random().toString(36).slice(2);
|
|
81
|
+
if (typeof crypto === "undefined" || !crypto.getRandomValues) throw new Error("[Pyreon] CSP nonce generation requires `crypto.getRandomValues` (Web Crypto API). No secure RNG is available in this environment. CSP nonces must be cryptographically random — falling back to `Math.random` would silently weaken XSS protection. Ensure Node 18+, Bun, Deno, an edge runtime, or a browser environment.");
|
|
82
|
+
const bytes = new Uint8Array(16);
|
|
83
|
+
crypto.getRandomValues(bytes);
|
|
84
|
+
let binary = "";
|
|
85
|
+
for (const byte of bytes) binary += String.fromCharCode(byte);
|
|
86
|
+
return typeof btoa === "function" ? btoa(binary) : Buffer.from(bytes).toString("base64");
|
|
77
87
|
}
|
|
78
88
|
/**
|
|
79
89
|
* CSP middleware — sets Content-Security-Policy header.
|
|
@@ -16,6 +16,10 @@ var __exportAll = (all, no_symbols) => {
|
|
|
16
16
|
}
|
|
17
17
|
return target;
|
|
18
18
|
};
|
|
19
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { get: (a, b) => (typeof require !== "undefined" ? require : a)[b] }) : x)(function(x) {
|
|
20
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
21
|
+
throw Error("Calling `require` for \"" + x + "\" in an environment that doesn't expose the `require` function. See https://rolldown.rs/in-depth/bundling-cjs#require-external-modules for more details.");
|
|
22
|
+
});
|
|
19
23
|
|
|
20
24
|
//#endregion
|
|
21
25
|
//#region src/fs-router.ts
|
|
@@ -44,7 +48,9 @@ const ROUTE_EXPORT_NAMES = [
|
|
|
44
48
|
"meta",
|
|
45
49
|
"renderMode",
|
|
46
50
|
"error",
|
|
47
|
-
"middleware"
|
|
51
|
+
"middleware",
|
|
52
|
+
"loaderKey",
|
|
53
|
+
"gcTime"
|
|
48
54
|
];
|
|
49
55
|
/**
|
|
50
56
|
* Detect which optional metadata exports a route file source declares.
|
|
@@ -85,6 +91,8 @@ function detectRouteExports(source) {
|
|
|
85
91
|
hasRenderMode: found.has("renderMode"),
|
|
86
92
|
hasError: found.has("error"),
|
|
87
93
|
hasMiddleware: found.has("middleware"),
|
|
94
|
+
hasLoaderKey: found.has("loaderKey"),
|
|
95
|
+
hasGcTime: found.has("gcTime"),
|
|
88
96
|
...metaLiteral !== void 0 ? { metaLiteral } : {},
|
|
89
97
|
...renderModeLiteral !== void 0 ? { renderModeLiteral } : {}
|
|
90
98
|
};
|
|
@@ -568,7 +576,9 @@ const EMPTY_EXPORTS = {
|
|
|
568
576
|
hasMeta: false,
|
|
569
577
|
hasRenderMode: false,
|
|
570
578
|
hasError: false,
|
|
571
|
-
hasMiddleware: false
|
|
579
|
+
hasMiddleware: false,
|
|
580
|
+
hasLoaderKey: false,
|
|
581
|
+
hasGcTime: false
|
|
572
582
|
};
|
|
573
583
|
/**
|
|
574
584
|
* True if a route file declares ANY metadata export.
|
|
@@ -576,7 +586,7 @@ const EMPTY_EXPORTS = {
|
|
|
576
586
|
* `import * as mod` (for metadata access) instead of lazy().
|
|
577
587
|
*/
|
|
578
588
|
function hasAnyMetaExport(exports) {
|
|
579
|
-
return exports.hasLoader || exports.hasGuard || exports.hasMeta || exports.hasRenderMode || exports.hasError || exports.hasMiddleware;
|
|
589
|
+
return exports.hasLoader || exports.hasGuard || exports.hasMeta || exports.hasRenderMode || exports.hasError || exports.hasMiddleware || exports.hasLoaderKey || exports.hasGcTime;
|
|
580
590
|
}
|
|
581
591
|
/**
|
|
582
592
|
* Parse a set of file paths (relative to routes dir) into FileRoute objects.
|
|
@@ -776,6 +786,8 @@ function generateRouteModuleFromRoutes(routes, routesDir, options) {
|
|
|
776
786
|
props.push(`${indent} component: ${mod}.default`);
|
|
777
787
|
if (exp.hasLoader) props.push(`${indent} loader: ${mod}.loader`);
|
|
778
788
|
if (exp.hasGuard) props.push(`${indent} beforeEnter: ${mod}.guard`);
|
|
789
|
+
if (exp.hasLoaderKey) props.push(`${indent} loaderKey: ${mod}.loaderKey`);
|
|
790
|
+
if (exp.hasGcTime) props.push(`${indent} gcTime: ${mod}.gcTime`);
|
|
779
791
|
if (exp.hasMeta || exp.hasRenderMode) {
|
|
780
792
|
const metaParts = [];
|
|
781
793
|
if (exp.hasMeta) metaParts.push(`...${mod}.meta`);
|
|
@@ -805,6 +817,14 @@ function generateRouteModuleFromRoutes(routes, routesDir, options) {
|
|
|
805
817
|
props.push(`${indent} component: ${comp}`);
|
|
806
818
|
if (exp.hasLoader) props.push(`${indent} loader: (ctx) => import("${fullPath}").then((m) => m.loader(ctx))`);
|
|
807
819
|
if (exp.hasGuard) props.push(`${indent} beforeEnter: (to, from) => import("${fullPath}").then((m) => m.guard(to, from))`);
|
|
820
|
+
if (exp.hasLoaderKey) {
|
|
821
|
+
const mod = nextModuleImport(page.filePath);
|
|
822
|
+
props.push(`${indent} loaderKey: ${mod}.loaderKey`);
|
|
823
|
+
}
|
|
824
|
+
if (exp.hasGcTime) {
|
|
825
|
+
const mod = nextModuleImport(page.filePath);
|
|
826
|
+
props.push(`${indent} gcTime: ${mod}.gcTime`);
|
|
827
|
+
}
|
|
808
828
|
emitInlineMeta(exp, props, indent);
|
|
809
829
|
if (errorName) {
|
|
810
830
|
const errorRef = exp.hasError ? `lazy(() => import("${fullPath}").then((m) => ({ default: m.error })))` : errorName;
|
|
@@ -816,6 +836,8 @@ function generateRouteModuleFromRoutes(routes, routesDir, options) {
|
|
|
816
836
|
props.push(`${indent} component: ${mod}.default`);
|
|
817
837
|
if (exp.hasLoader) props.push(`${indent} loader: ${mod}.loader`);
|
|
818
838
|
if (exp.hasGuard) props.push(`${indent} beforeEnter: ${mod}.guard`);
|
|
839
|
+
if (exp.hasLoaderKey) props.push(`${indent} loaderKey: ${mod}.loaderKey`);
|
|
840
|
+
if (exp.hasGcTime) props.push(`${indent} gcTime: ${mod}.gcTime`);
|
|
819
841
|
if (exp.hasMeta || exp.hasRenderMode) {
|
|
820
842
|
const metaParts = [];
|
|
821
843
|
if (exp.hasMeta) metaParts.push(`...${mod}.meta`);
|
|
@@ -849,6 +871,8 @@ function generateRouteModuleFromRoutes(routes, routesDir, options) {
|
|
|
849
871
|
if (layoutMod !== void 0) {
|
|
850
872
|
if (exp.hasLoader) props.push(`${indent}loader: ${layoutMod}.loader`);
|
|
851
873
|
if (exp.hasGuard) props.push(`${indent}beforeEnter: ${layoutMod}.guard`);
|
|
874
|
+
if (exp.hasLoaderKey) props.push(`${indent}loaderKey: ${layoutMod}.loaderKey`);
|
|
875
|
+
if (exp.hasGcTime) props.push(`${indent}gcTime: ${layoutMod}.gcTime`);
|
|
852
876
|
if (exp.hasMeta || exp.hasRenderMode) {
|
|
853
877
|
const metaParts = [];
|
|
854
878
|
if (exp.hasMeta) metaParts.push(`...${layoutMod}.meta`);
|
|
@@ -885,14 +909,26 @@ function generateRouteModuleFromRoutes(routes, routesDir, options) {
|
|
|
885
909
|
/**
|
|
886
910
|
* Generate a virtual module that maps URL patterns to their middleware exports.
|
|
887
911
|
* Used by the server entry to dispatch per-route middleware.
|
|
912
|
+
*
|
|
913
|
+
* Detects whether each route file actually exports `middleware` (via
|
|
914
|
+
* `detectRouteExports` source scanning) and only emits an import for files
|
|
915
|
+
* that do. The `lazy()` import path tolerates missing exports, but the SSG
|
|
916
|
+
* static-import path fails Rolldown's missing-export check at build time —
|
|
917
|
+
* skipping no-middleware files keeps both paths working.
|
|
888
918
|
*/
|
|
889
919
|
function generateMiddlewareModule(files, routesDir) {
|
|
920
|
+
const { readFileSync } = __require("node:fs");
|
|
890
921
|
const routes = parseFileRoutes(files);
|
|
891
922
|
const imports = [];
|
|
892
923
|
const entries = [];
|
|
893
924
|
let counter = 0;
|
|
894
925
|
for (const route of routes) {
|
|
895
926
|
if (route.isLayout || route.isError || route.isLoading || route.isNotFound) continue;
|
|
927
|
+
let hasMw = false;
|
|
928
|
+
try {
|
|
929
|
+
hasMw = detectRouteExports(readFileSync(`${routesDir}/${route.filePath}`, "utf-8")).hasMiddleware;
|
|
930
|
+
} catch {}
|
|
931
|
+
if (!hasMw) continue;
|
|
896
932
|
const name = `_mw${counter++}`;
|
|
897
933
|
const fullPath = `${routesDir}/${route.filePath}`;
|
|
898
934
|
imports.push(`import { middleware as ${name} } from "${fullPath}"`);
|
|
@@ -937,7 +973,8 @@ async function scanRouteFiles(routesDir) {
|
|
|
937
973
|
*/
|
|
938
974
|
async function scanRouteFilesWithExports(routesDir, defaultMode = "ssr") {
|
|
939
975
|
const { readFile } = await import("node:fs/promises");
|
|
940
|
-
const
|
|
976
|
+
const { isApiRoute } = await import("./api-routes-DANluJic.js").then((n) => n.t);
|
|
977
|
+
const files = (await scanRouteFiles(routesDir)).filter((f) => !isApiRoute(f));
|
|
941
978
|
const exportsMap = /* @__PURE__ */ new Map();
|
|
942
979
|
await Promise.all(files.map(async (filePath) => {
|
|
943
980
|
try {
|
|
@@ -951,5 +988,5 @@ async function scanRouteFilesWithExports(routesDir, defaultMode = "ssr") {
|
|
|
951
988
|
}
|
|
952
989
|
|
|
953
990
|
//#endregion
|
|
954
|
-
export { generateRouteModuleFromRoutes as a, scanRouteFilesWithExports as c, generateRouteModule as i, fs_router_exports as n, parseFileRoutes as o, generateMiddlewareModule as r, scanRouteFiles as s, filePathToUrlPath as t };
|
|
955
|
-
//# sourceMappingURL=fs-router-
|
|
991
|
+
export { generateRouteModuleFromRoutes as a, scanRouteFilesWithExports as c, generateRouteModule as i, __exportAll as l, fs_router_exports as n, parseFileRoutes as o, generateMiddlewareModule as r, scanRouteFiles as s, filePathToUrlPath as t };
|
|
992
|
+
//# sourceMappingURL=fs-router-ZebyutPa.js.map
|
package/lib/image-plugin.js
CHANGED
|
@@ -11,9 +11,13 @@ function warnSharpMissing() {
|
|
|
11
11
|
}
|
|
12
12
|
/** Built-in CDN providers. */
|
|
13
13
|
const cdnProviders = {
|
|
14
|
+
/** Cloudinary: `https://res.cloudinary.com/{cloud}/image/upload/...` */
|
|
14
15
|
cloudinary: (cloudName) => (src, { width, quality, format }) => `https://res.cloudinary.com/${cloudName}/image/upload/w_${width},q_${quality},f_${format}/${src}`,
|
|
16
|
+
/** Imgix: `https://{domain}.imgix.net/...?w=...&q=...&fm=...` */
|
|
15
17
|
imgix: (domain) => (src, { width, quality, format }) => `https://${domain}.imgix.net/${src}?w=${width}&q=${quality}&fm=${format}&auto=format`,
|
|
18
|
+
/** Vercel Image Optimization: `/_next/image?url=...&w=...&q=...` */
|
|
16
19
|
vercel: () => (src, { width, quality }) => `/_vercel/image?url=${encodeURIComponent(src)}&w=${width}&q=${quality}`,
|
|
20
|
+
/** Bunny CDN: `https://{pullZone}.b-cdn.net/...?width=...&quality=...` */
|
|
17
21
|
bunny: (pullZone) => (src, { width, quality }) => `https://${pullZone}.b-cdn.net/${src}?width=${width}&quality=${quality}`
|
|
18
22
|
};
|
|
19
23
|
const IMAGE_EXT_RE = /\.(jpe?g|png|webp|avif)$/i;
|
package/lib/image.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createRef, onMount, onUnmount } from "@pyreon/core";
|
|
2
2
|
import { signal } from "@pyreon/reactivity";
|
|
3
|
+
import { jsx, jsxs } from "@pyreon/core/jsx-runtime";
|
|
3
4
|
|
|
4
5
|
//#region src/utils/use-intersection-observer.ts
|
|
5
6
|
/**
|
|
@@ -25,56 +26,6 @@ function useIntersectionObserver(getElement, onIntersect, rootMargin = "200px")
|
|
|
25
26
|
});
|
|
26
27
|
}
|
|
27
28
|
|
|
28
|
-
//#endregion
|
|
29
|
-
//#region ../../core/core/lib/jsx-runtime.js
|
|
30
|
-
/**
|
|
31
|
-
* Hyperscript function — the compiled output of JSX.
|
|
32
|
-
* `<div class="x">hello</div>` → `h("div", { class: "x" }, "hello")`
|
|
33
|
-
*
|
|
34
|
-
* Generic on P so TypeScript validates props match the component's signature
|
|
35
|
-
* at the call site, then stores the result in the loosely-typed VNode.
|
|
36
|
-
*/
|
|
37
|
-
/** Shared empty props sentinel — identity-checked in mountElement to skip applyProps. */
|
|
38
|
-
const EMPTY_PROPS = {};
|
|
39
|
-
function h(type, props, ...children) {
|
|
40
|
-
return {
|
|
41
|
-
type,
|
|
42
|
-
props: props ?? EMPTY_PROPS,
|
|
43
|
-
children: normalizeChildren(children),
|
|
44
|
-
key: props?.key ?? null
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
function normalizeChildren(children) {
|
|
48
|
-
for (let i = 0; i < children.length; i++) if (Array.isArray(children[i])) return flattenChildren(children);
|
|
49
|
-
return children;
|
|
50
|
-
}
|
|
51
|
-
function flattenChildren(children) {
|
|
52
|
-
const result = [];
|
|
53
|
-
for (const child of children) if (Array.isArray(child)) result.push(...flattenChildren(child));
|
|
54
|
-
else result.push(child);
|
|
55
|
-
return result;
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* JSX automatic runtime.
|
|
59
|
-
*
|
|
60
|
-
* When tsconfig has `"jsxImportSource": "@pyreon/core"`, the TS/bundler compiler
|
|
61
|
-
* rewrites JSX to imports from this file automatically:
|
|
62
|
-
* <div class="x" /> → jsx("div", { class: "x" })
|
|
63
|
-
*/
|
|
64
|
-
function jsx(type, props, key) {
|
|
65
|
-
const { children, ...rest } = props;
|
|
66
|
-
const propsWithKey = key != null ? {
|
|
67
|
-
...rest,
|
|
68
|
-
key
|
|
69
|
-
} : rest;
|
|
70
|
-
if (typeof type === "function") return h(type, children !== void 0 ? {
|
|
71
|
-
...propsWithKey,
|
|
72
|
-
children
|
|
73
|
-
} : propsWithKey);
|
|
74
|
-
return h(type, propsWithKey, ...children === void 0 ? [] : Array.isArray(children) ? children : [children]);
|
|
75
|
-
}
|
|
76
|
-
const jsxs = jsx;
|
|
77
|
-
|
|
78
29
|
//#endregion
|
|
79
30
|
//#region src/image.tsx
|
|
80
31
|
/**
|
package/lib/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createContext, createRef, onMount, onUnmount } from "@pyreon/core";
|
|
2
2
|
import { effect, signal } from "@pyreon/reactivity";
|
|
3
|
+
import { jsx, jsxs } from "@pyreon/core/jsx-runtime";
|
|
3
4
|
import { useRouter } from "@pyreon/router";
|
|
4
5
|
import { useHead } from "@pyreon/head";
|
|
5
6
|
|
|
@@ -27,56 +28,6 @@ function useIntersectionObserver(getElement, onIntersect, rootMargin = "200px")
|
|
|
27
28
|
});
|
|
28
29
|
}
|
|
29
30
|
|
|
30
|
-
//#endregion
|
|
31
|
-
//#region ../../core/core/lib/jsx-runtime.js
|
|
32
|
-
/**
|
|
33
|
-
* Hyperscript function — the compiled output of JSX.
|
|
34
|
-
* `<div class="x">hello</div>` → `h("div", { class: "x" }, "hello")`
|
|
35
|
-
*
|
|
36
|
-
* Generic on P so TypeScript validates props match the component's signature
|
|
37
|
-
* at the call site, then stores the result in the loosely-typed VNode.
|
|
38
|
-
*/
|
|
39
|
-
/** Shared empty props sentinel — identity-checked in mountElement to skip applyProps. */
|
|
40
|
-
const EMPTY_PROPS = {};
|
|
41
|
-
function h(type, props, ...children) {
|
|
42
|
-
return {
|
|
43
|
-
type,
|
|
44
|
-
props: props ?? EMPTY_PROPS,
|
|
45
|
-
children: normalizeChildren(children),
|
|
46
|
-
key: props?.key ?? null
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
function normalizeChildren(children) {
|
|
50
|
-
for (let i = 0; i < children.length; i++) if (Array.isArray(children[i])) return flattenChildren(children);
|
|
51
|
-
return children;
|
|
52
|
-
}
|
|
53
|
-
function flattenChildren(children) {
|
|
54
|
-
const result = [];
|
|
55
|
-
for (const child of children) if (Array.isArray(child)) result.push(...flattenChildren(child));
|
|
56
|
-
else result.push(child);
|
|
57
|
-
return result;
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* JSX automatic runtime.
|
|
61
|
-
*
|
|
62
|
-
* When tsconfig has `"jsxImportSource": "@pyreon/core"`, the TS/bundler compiler
|
|
63
|
-
* rewrites JSX to imports from this file automatically:
|
|
64
|
-
* <div class="x" /> → jsx("div", { class: "x" })
|
|
65
|
-
*/
|
|
66
|
-
function jsx(type, props, key) {
|
|
67
|
-
const { children, ...rest } = props;
|
|
68
|
-
const propsWithKey = key != null ? {
|
|
69
|
-
...rest,
|
|
70
|
-
key
|
|
71
|
-
} : rest;
|
|
72
|
-
if (typeof type === "function") return h(type, children !== void 0 ? {
|
|
73
|
-
...propsWithKey,
|
|
74
|
-
children
|
|
75
|
-
} : propsWithKey);
|
|
76
|
-
return h(type, propsWithKey, ...children === void 0 ? [] : Array.isArray(children) ? children : [children]);
|
|
77
|
-
}
|
|
78
|
-
const jsxs = jsx;
|
|
79
|
-
|
|
80
31
|
//#endregion
|
|
81
32
|
//#region src/image.tsx
|
|
82
33
|
/**
|
package/lib/link.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createRef, onMount, onUnmount } from "@pyreon/core";
|
|
2
2
|
import { useRouter } from "@pyreon/router";
|
|
3
|
+
import { jsx } from "@pyreon/core/jsx-runtime";
|
|
3
4
|
|
|
4
5
|
//#region src/utils/use-intersection-observer.ts
|
|
5
6
|
/**
|
|
@@ -25,55 +26,6 @@ function useIntersectionObserver(getElement, onIntersect, rootMargin = "200px")
|
|
|
25
26
|
});
|
|
26
27
|
}
|
|
27
28
|
|
|
28
|
-
//#endregion
|
|
29
|
-
//#region ../../core/core/lib/jsx-runtime.js
|
|
30
|
-
/**
|
|
31
|
-
* Hyperscript function — the compiled output of JSX.
|
|
32
|
-
* `<div class="x">hello</div>` → `h("div", { class: "x" }, "hello")`
|
|
33
|
-
*
|
|
34
|
-
* Generic on P so TypeScript validates props match the component's signature
|
|
35
|
-
* at the call site, then stores the result in the loosely-typed VNode.
|
|
36
|
-
*/
|
|
37
|
-
/** Shared empty props sentinel — identity-checked in mountElement to skip applyProps. */
|
|
38
|
-
const EMPTY_PROPS = {};
|
|
39
|
-
function h(type, props, ...children) {
|
|
40
|
-
return {
|
|
41
|
-
type,
|
|
42
|
-
props: props ?? EMPTY_PROPS,
|
|
43
|
-
children: normalizeChildren(children),
|
|
44
|
-
key: props?.key ?? null
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
function normalizeChildren(children) {
|
|
48
|
-
for (let i = 0; i < children.length; i++) if (Array.isArray(children[i])) return flattenChildren(children);
|
|
49
|
-
return children;
|
|
50
|
-
}
|
|
51
|
-
function flattenChildren(children) {
|
|
52
|
-
const result = [];
|
|
53
|
-
for (const child of children) if (Array.isArray(child)) result.push(...flattenChildren(child));
|
|
54
|
-
else result.push(child);
|
|
55
|
-
return result;
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* JSX automatic runtime.
|
|
59
|
-
*
|
|
60
|
-
* When tsconfig has `"jsxImportSource": "@pyreon/core"`, the TS/bundler compiler
|
|
61
|
-
* rewrites JSX to imports from this file automatically:
|
|
62
|
-
* <div class="x" /> → jsx("div", { class: "x" })
|
|
63
|
-
*/
|
|
64
|
-
function jsx(type, props, key) {
|
|
65
|
-
const { children, ...rest } = props;
|
|
66
|
-
const propsWithKey = key != null ? {
|
|
67
|
-
...rest,
|
|
68
|
-
key
|
|
69
|
-
} : rest;
|
|
70
|
-
if (typeof type === "function") return h(type, children !== void 0 ? {
|
|
71
|
-
...propsWithKey,
|
|
72
|
-
children
|
|
73
|
-
} : propsWithKey);
|
|
74
|
-
return h(type, propsWithKey, ...children === void 0 ? [] : Array.isArray(children) ? children : [children]);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
29
|
//#endregion
|
|
78
30
|
//#region src/link.tsx
|
|
79
31
|
const MAX_PREFETCH_CACHE = 200;
|
package/lib/script.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createRef, onMount, onUnmount } from "@pyreon/core";
|
|
2
|
+
import { jsx } from "@pyreon/core/jsx-runtime";
|
|
2
3
|
|
|
3
4
|
//#region src/utils/use-intersection-observer.ts
|
|
4
5
|
/**
|
|
@@ -24,55 +25,6 @@ function useIntersectionObserver(getElement, onIntersect, rootMargin = "200px")
|
|
|
24
25
|
});
|
|
25
26
|
}
|
|
26
27
|
|
|
27
|
-
//#endregion
|
|
28
|
-
//#region ../../core/core/lib/jsx-runtime.js
|
|
29
|
-
/**
|
|
30
|
-
* Hyperscript function — the compiled output of JSX.
|
|
31
|
-
* `<div class="x">hello</div>` → `h("div", { class: "x" }, "hello")`
|
|
32
|
-
*
|
|
33
|
-
* Generic on P so TypeScript validates props match the component's signature
|
|
34
|
-
* at the call site, then stores the result in the loosely-typed VNode.
|
|
35
|
-
*/
|
|
36
|
-
/** Shared empty props sentinel — identity-checked in mountElement to skip applyProps. */
|
|
37
|
-
const EMPTY_PROPS = {};
|
|
38
|
-
function h(type, props, ...children) {
|
|
39
|
-
return {
|
|
40
|
-
type,
|
|
41
|
-
props: props ?? EMPTY_PROPS,
|
|
42
|
-
children: normalizeChildren(children),
|
|
43
|
-
key: props?.key ?? null
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
function normalizeChildren(children) {
|
|
47
|
-
for (let i = 0; i < children.length; i++) if (Array.isArray(children[i])) return flattenChildren(children);
|
|
48
|
-
return children;
|
|
49
|
-
}
|
|
50
|
-
function flattenChildren(children) {
|
|
51
|
-
const result = [];
|
|
52
|
-
for (const child of children) if (Array.isArray(child)) result.push(...flattenChildren(child));
|
|
53
|
-
else result.push(child);
|
|
54
|
-
return result;
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* JSX automatic runtime.
|
|
58
|
-
*
|
|
59
|
-
* When tsconfig has `"jsxImportSource": "@pyreon/core"`, the TS/bundler compiler
|
|
60
|
-
* rewrites JSX to imports from this file automatically:
|
|
61
|
-
* <div class="x" /> → jsx("div", { class: "x" })
|
|
62
|
-
*/
|
|
63
|
-
function jsx(type, props, key) {
|
|
64
|
-
const { children, ...rest } = props;
|
|
65
|
-
const propsWithKey = key != null ? {
|
|
66
|
-
...rest,
|
|
67
|
-
key
|
|
68
|
-
} : rest;
|
|
69
|
-
if (typeof type === "function") return h(type, children !== void 0 ? {
|
|
70
|
-
...propsWithKey,
|
|
71
|
-
children
|
|
72
|
-
} : propsWithKey);
|
|
73
|
-
return h(type, propsWithKey, ...children === void 0 ? [] : Array.isArray(children) ? children : [children]);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
28
|
//#endregion
|
|
77
29
|
//#region src/script.tsx
|
|
78
30
|
/**
|