@devlusoft/devix 0.2.0 → 0.2.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/cli/build.js +30 -308
- package/dist/cli/build.js.map +3 -3
- package/dist/cli/dev.js +32 -395
- package/dist/cli/dev.js.map +3 -3
- package/dist/cli/generate.js +30 -434
- package/dist/cli/generate.js.map +3 -3
- package/dist/cli/index.js +33 -698
- package/dist/cli/index.js.map +3 -3
- package/dist/cli/start.js +1 -89
- package/dist/cli/start.js.map +2 -2
- package/dist/config.js +1 -16
- package/dist/config.js.map +2 -2
- package/dist/runtime/api-context.js +1 -17
- package/dist/runtime/api-context.js.map +2 -2
- package/dist/runtime/client-router.js +1 -58
- package/dist/runtime/client-router.js.map +2 -2
- package/dist/runtime/context.js +1 -14
- package/dist/runtime/context.js.map +2 -2
- package/dist/runtime/error-boundary.js +1 -36
- package/dist/runtime/error-boundary.js.map +2 -2
- package/dist/runtime/fetch.js +1 -34
- package/dist/runtime/fetch.js.map +2 -2
- package/dist/runtime/head.js +1 -68
- package/dist/runtime/head.js.map +2 -2
- package/dist/runtime/index.d.ts +1 -0
- package/dist/runtime/index.js +1 -367
- package/dist/runtime/index.js.map +3 -3
- package/dist/runtime/link.js +1 -42
- package/dist/runtime/link.js.map +2 -2
- package/dist/runtime/metadata.js +1 -21
- package/dist/runtime/metadata.js.map +2 -2
- package/dist/runtime/router-provider.js +1 -258
- package/dist/runtime/router-provider.js.map +2 -2
- package/dist/server/api-router.js +1 -64
- package/dist/server/api-router.js.map +2 -2
- package/dist/server/api.js +1 -123
- package/dist/server/api.js.map +2 -2
- package/dist/server/collect-css.js +1 -14
- package/dist/server/collect-css.js.map +2 -2
- package/dist/server/index.js +1 -132
- package/dist/server/index.js.map +2 -2
- package/dist/server/pages-router.js +1 -63
- package/dist/server/pages-router.js.map +2 -2
- package/dist/server/render.js +1 -305
- package/dist/server/render.js.map +2 -2
- package/dist/server/routes.js +1 -41
- package/dist/server/routes.js.map +2 -2
- package/dist/utils/async.js +1 -13
- package/dist/utils/async.js.map +2 -2
- package/dist/utils/banner.js +1 -33
- package/dist/utils/banner.js.map +2 -2
- package/dist/utils/cookies.js +1 -28
- package/dist/utils/cookies.js.map +2 -2
- package/dist/utils/duration.js +1 -21
- package/dist/utils/duration.js.map +2 -2
- package/dist/utils/env.js +1 -13
- package/dist/utils/env.js.map +2 -2
- package/dist/utils/html.js +1 -11
- package/dist/utils/html.js.map +2 -2
- package/dist/utils/patterns.js +1 -7
- package/dist/utils/patterns.js.map +2 -2
- package/dist/utils/response.d.ts +4 -1
- package/dist/utils/response.js +1 -9
- package/dist/utils/response.js.map +3 -3
- package/dist/vite/codegen/api.js +6 -12
- package/dist/vite/codegen/api.js.map +2 -2
- package/dist/vite/codegen/client-routes.js +6 -12
- package/dist/vite/codegen/client-routes.js.map +2 -2
- package/dist/vite/codegen/context.js +2 -8
- package/dist/vite/codegen/context.js.map +2 -2
- package/dist/vite/codegen/entry-client.js +4 -10
- package/dist/vite/codegen/entry-client.js.map +2 -2
- package/dist/vite/codegen/extract-methods.js +1 -15
- package/dist/vite/codegen/extract-methods.js.map +2 -2
- package/dist/vite/codegen/render.js +6 -12
- package/dist/vite/codegen/render.js.map +2 -2
- package/dist/vite/codegen/routes-dts.js +11 -49
- package/dist/vite/codegen/routes-dts.js.map +3 -3
- package/dist/vite/codegen/scan-api.js +1 -77
- package/dist/vite/codegen/scan-api.js.map +3 -3
- package/dist/vite/codegen/write-routes-dts.js +1 -16
- package/dist/vite/codegen/write-routes-dts.js.map +2 -2
- package/dist/vite/index.js +30 -247
- package/dist/vite/index.js.map +3 -3
- package/package.json +2 -2
|
@@ -1,37 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
import { Component } from "react";
|
|
3
|
-
import { jsx } from "react/jsx-runtime";
|
|
4
|
-
var DevixErrorBoundary = class extends Component {
|
|
5
|
-
state = { error: null };
|
|
6
|
-
static getDerivedStateFromError(err) {
|
|
7
|
-
if (err instanceof DevixError) {
|
|
8
|
-
return {
|
|
9
|
-
error: { statusCode: err.statusCode, message: err.message }
|
|
10
|
-
};
|
|
11
|
-
}
|
|
12
|
-
return {
|
|
13
|
-
error: { statusCode: 500, message: err instanceof Error ? err.message : "Unknown error" }
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
|
-
render() {
|
|
17
|
-
if (this.state.error && this.props.ErrorPage) {
|
|
18
|
-
return /* @__PURE__ */ jsx(this.props.ErrorPage, { ...this.state.error });
|
|
19
|
-
}
|
|
20
|
-
if (this.state.error) {
|
|
21
|
-
return /* @__PURE__ */ jsx("h1", { children: this.state.error.statusCode });
|
|
22
|
-
}
|
|
23
|
-
return this.props.children;
|
|
24
|
-
}
|
|
25
|
-
};
|
|
26
|
-
var DevixError = class extends Error {
|
|
27
|
-
statusCode;
|
|
28
|
-
constructor(statusCode, message) {
|
|
29
|
-
super(message);
|
|
30
|
-
this.statusCode = statusCode;
|
|
31
|
-
}
|
|
32
|
-
};
|
|
33
|
-
export {
|
|
34
|
-
DevixError,
|
|
35
|
-
DevixErrorBoundary
|
|
36
|
-
};
|
|
1
|
+
import{Component as a}from"react";import{jsx as s}from"react/jsx-runtime";var t=class extends a{state={error:null};static getDerivedStateFromError(r){return r instanceof e?{error:{statusCode:r.statusCode,message:r.message}}:{error:{statusCode:500,message:r instanceof Error?r.message:"Unknown error"}}}render(){return this.state.error&&this.props.ErrorPage?s(this.props.ErrorPage,{...this.state.error}):this.state.error?s("h1",{children:this.state.error.statusCode}):this.props.children}},e=class extends Error{statusCode;constructor(r,n){super(n),this.statusCode=r}};export{e as DevixError,t as DevixErrorBoundary};
|
|
37
2
|
//# sourceMappingURL=error-boundary.js.map
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/runtime/error-boundary.tsx"],
|
|
4
4
|
"sourcesContent": ["import {Component, ComponentType, ReactNode} from \"react\";\nimport {ErrorProps} from \"../server/types\";\n\ninterface Props {\n ErrorPage?: ComponentType<ErrorProps>\n children: ReactNode\n}\n\ninterface State {\n error: ErrorProps | null\n}\n\nexport class DevixErrorBoundary extends Component<Props, State> {\n state: State = { error: null }\n\n static getDerivedStateFromError(err: unknown): State {\n if (err instanceof DevixError) {\n return {\n error: {statusCode: err.statusCode, message: err.message}\n }\n }\n return {\n error: {statusCode: 500, message: err instanceof Error ? err.message : 'Unknown error'}\n }\n }\n\n render() {\n if (this.state.error && this.props.ErrorPage) {\n return <this.props.ErrorPage {...this.state.error} />\n }\n if (this.state.error) {\n return <h1>{this.state.error.statusCode}</h1>\n }\n return this.props.children\n }\n}\n\nexport class DevixError extends Error {\n statusCode: number\n constructor(statusCode: number, message: string) {\n super(message)\n this.statusCode = statusCode\n }\n}\n"],
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": []
|
|
5
|
+
"mappings": "AAAA,OAAQ,aAAAA,MAA0C,QA4B/B,cAAAC,MAAA,oBAhBZ,IAAMC,EAAN,cAAiCF,CAAwB,CAC5D,MAAe,CAAE,MAAO,IAAK,EAE7B,OAAO,yBAAyBG,EAAqB,CACjD,OAAIA,aAAeC,EACR,CACH,MAAO,CAAC,WAAYD,EAAI,WAAY,QAASA,EAAI,OAAO,CAC5D,EAEI,CACJ,MAAO,CAAC,WAAY,IAAK,QAASA,aAAe,MAAQA,EAAI,QAAU,eAAe,CAC1F,CACJ,CAEA,QAAS,CACL,OAAI,KAAK,MAAM,OAAS,KAAK,MAAM,UACxBF,EAAC,KAAK,MAAM,UAAX,CAAsB,GAAG,KAAK,MAAM,MAAO,EAEnD,KAAK,MAAM,MACJA,EAAC,MAAI,cAAK,MAAM,MAAM,WAAW,EAErC,KAAK,MAAM,QACtB,CACJ,EAEaG,EAAN,cAAyB,KAAM,CAClC,WACA,YAAYC,EAAoBC,EAAiB,CAC7C,MAAMA,CAAO,EACb,KAAK,WAAaD,CACtB,CACJ",
|
|
6
|
+
"names": ["Component", "jsx", "DevixErrorBoundary", "err", "DevixError", "statusCode", "message"]
|
|
7
7
|
}
|
package/dist/runtime/fetch.js
CHANGED
|
@@ -1,35 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
var FetchError = class extends Error {
|
|
3
|
-
constructor(status, statusText, response) {
|
|
4
|
-
super(`HTTP ${status}: ${statusText}`);
|
|
5
|
-
this.status = status;
|
|
6
|
-
this.statusText = statusText;
|
|
7
|
-
this.response = response;
|
|
8
|
-
this.name = "FetchError";
|
|
9
|
-
}
|
|
10
|
-
};
|
|
11
|
-
async function $fetch(path, options) {
|
|
12
|
-
const method = options?.method ?? "GET";
|
|
13
|
-
const headers = new Headers(options?.headers);
|
|
14
|
-
let body;
|
|
15
|
-
if (options?.body !== void 0) {
|
|
16
|
-
body = JSON.stringify(options.body);
|
|
17
|
-
if (!headers.has("Content-Type")) {
|
|
18
|
-
headers.set("Content-Type", "application/json");
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
const response = await fetch(path, { method, headers, body, signal: options?.signal });
|
|
22
|
-
if (!response.ok) {
|
|
23
|
-
throw new FetchError(response.status, response.statusText, response);
|
|
24
|
-
}
|
|
25
|
-
const contentType = response.headers.get("Content-Type") ?? "";
|
|
26
|
-
if (contentType.includes("application/json")) {
|
|
27
|
-
return response.json();
|
|
28
|
-
}
|
|
29
|
-
return response.text();
|
|
30
|
-
}
|
|
31
|
-
export {
|
|
32
|
-
$fetch,
|
|
33
|
-
FetchError
|
|
34
|
-
};
|
|
1
|
+
var r=class extends Error{constructor(s,n,o){super(`HTTP ${s}: ${n}`);this.status=s;this.statusText=n;this.response=o;this.name="FetchError"}};async function p(i,t){let s=t?.method??"GET",n=new Headers(t?.headers),o;t?.body!==void 0&&(o=JSON.stringify(t.body),n.has("Content-Type")||n.set("Content-Type","application/json"));let e=await fetch(i,{method:s,headers:n,body:o,signal:t?.signal});if(!e.ok)throw new r(e.status,e.statusText,e);return(e.headers.get("Content-Type")??"").includes("application/json")?e.json():e.text()}export{p as $fetch,r as FetchError};
|
|
35
2
|
//# sourceMappingURL=fetch.js.map
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/runtime/fetch.ts"],
|
|
4
4
|
"sourcesContent": ["export interface ApiRoutes {}\n\ntype HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS'\n\nexport interface FetchOptions<M extends HttpMethod = 'GET'> {\n method?: M\n body?: unknown\n headers?: HeadersInit\n signal?: AbortSignal\n}\n\ntype ApiKey<M extends HttpMethod, P extends string> = `${M} ${P}`\n\ntype InferResult<M extends HttpMethod, P extends string> =\n ApiKey<M, P> extends keyof ApiRoutes\n ? ApiRoutes[ApiKey<M, P>]\n : unknown\n\nexport class FetchError extends Error {\n constructor(\n public readonly status: number,\n public readonly statusText: string,\n public readonly response: Response,\n ) {\n super(`HTTP ${status}: ${statusText}`)\n this.name = 'FetchError'\n }\n}\n\nexport async function $fetch<\n P extends string,\n M extends HttpMethod = 'GET',\n>(path: P, options?: FetchOptions<M>): Promise<InferResult<M, P>> {\n const method = (options?.method ?? 'GET') as string\n const headers = new Headers(options?.headers)\n\n let body: BodyInit | undefined\n if (options?.body !== undefined) {\n body = JSON.stringify(options.body)\n if (!headers.has('Content-Type')) {\n headers.set('Content-Type', 'application/json')\n }\n }\n\n const response = await fetch(path, {method, headers, body, signal: options?.signal})\n\n if (!response.ok) {\n throw new FetchError(response.status, response.statusText, response)\n }\n\n const contentType = response.headers.get('Content-Type') ?? ''\n if (contentType.includes('application/json')) {\n return response.json() as Promise<InferResult<M, P>>\n }\n\n return response.text() as unknown as Promise<InferResult<M, P>>\n}\n"],
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": []
|
|
5
|
+
"mappings": "AAkBO,IAAMA,EAAN,cAAyB,KAAM,CAClC,YACoBC,EACAC,EACAC,EAClB,CACE,MAAM,QAAQF,CAAM,KAAKC,CAAU,EAAE,EAJrB,YAAAD,EACA,gBAAAC,EACA,cAAAC,EAGhB,KAAK,KAAO,YAChB,CACJ,EAEA,eAAsBC,EAGpBC,EAASC,EAAuD,CAC9D,IAAMC,EAAUD,GAAS,QAAU,MAC7BE,EAAU,IAAI,QAAQF,GAAS,OAAO,EAExCG,EACAH,GAAS,OAAS,SAClBG,EAAO,KAAK,UAAUH,EAAQ,IAAI,EAC7BE,EAAQ,IAAI,cAAc,GAC3BA,EAAQ,IAAI,eAAgB,kBAAkB,GAItD,IAAML,EAAW,MAAM,MAAME,EAAM,CAAC,OAAAE,EAAQ,QAAAC,EAAS,KAAAC,EAAM,OAAQH,GAAS,MAAM,CAAC,EAEnF,GAAI,CAACH,EAAS,GACV,MAAM,IAAIH,EAAWG,EAAS,OAAQA,EAAS,WAAYA,CAAQ,EAIvE,OADoBA,EAAS,QAAQ,IAAI,cAAc,GAAK,IAC5C,SAAS,kBAAkB,EAChCA,EAAS,KAAK,EAGlBA,EAAS,KAAK,CACzB",
|
|
6
|
+
"names": ["FetchError", "status", "statusText", "response", "$fetch", "path", "options", "method", "headers", "body"]
|
|
7
7
|
}
|
package/dist/runtime/head.js
CHANGED
|
@@ -1,69 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
import { Fragment, jsx } from "react/jsx-runtime";
|
|
3
|
-
function collectTags(metadata, viewport) {
|
|
4
|
-
const tags = [];
|
|
5
|
-
if (metadata.title)
|
|
6
|
-
tags.push({ tag: "title", children: metadata.title });
|
|
7
|
-
if (metadata.description)
|
|
8
|
-
tags.push({ tag: "meta", name: "description", content: metadata.description });
|
|
9
|
-
if (metadata.keywords?.length)
|
|
10
|
-
tags.push({ tag: "meta", name: "keywords", content: metadata.keywords.join(", ") });
|
|
11
|
-
const ogTitle = metadata.og?.title ?? metadata.title;
|
|
12
|
-
if (ogTitle) tags.push({ tag: "meta", property: "og:title", content: ogTitle });
|
|
13
|
-
const ogDesc = metadata.og?.description ?? metadata.description;
|
|
14
|
-
if (ogDesc) tags.push({ tag: "meta", property: "og:description", content: ogDesc });
|
|
15
|
-
if (metadata.og?.image) tags.push({ tag: "meta", property: "og:image", content: metadata.og.image });
|
|
16
|
-
if (metadata.og?.type) tags.push({ tag: "meta", property: "og:type", content: metadata.og.type });
|
|
17
|
-
if (metadata.og?.url) tags.push({ tag: "meta", property: "og:url", content: metadata.og.url });
|
|
18
|
-
const twTitle = metadata.twitter?.title ?? metadata.title;
|
|
19
|
-
if (twTitle) tags.push({ tag: "meta", name: "twitter:title", content: twTitle });
|
|
20
|
-
const twDesc = metadata.twitter?.description ?? metadata.description;
|
|
21
|
-
if (twDesc) tags.push({ tag: "meta", name: "twitter:description", content: twDesc });
|
|
22
|
-
if (metadata.twitter?.card) tags.push({
|
|
23
|
-
tag: "meta",
|
|
24
|
-
name: "twitter:card",
|
|
25
|
-
content: metadata.twitter.card
|
|
26
|
-
});
|
|
27
|
-
if (metadata.twitter?.image) tags.push({
|
|
28
|
-
tag: "meta",
|
|
29
|
-
name: "twitter:image",
|
|
30
|
-
content: metadata.twitter.image
|
|
31
|
-
});
|
|
32
|
-
if (metadata.twitter?.creator) tags.push({
|
|
33
|
-
tag: "meta",
|
|
34
|
-
name: "twitter:creator",
|
|
35
|
-
content: metadata.twitter.creator
|
|
36
|
-
});
|
|
37
|
-
if (metadata.canonical) tags.push({ tag: "link", rel: "canonical", href: metadata.canonical });
|
|
38
|
-
if (metadata.robots) tags.push({ tag: "meta", name: "robots", content: metadata.robots });
|
|
39
|
-
if (metadata.alternates) {
|
|
40
|
-
for (const [lang, href] of Object.entries(metadata.alternates))
|
|
41
|
-
tags.push({ tag: "link", rel: "alternate", href, hrefLang: lang });
|
|
42
|
-
}
|
|
43
|
-
if (viewport) {
|
|
44
|
-
const parts = [];
|
|
45
|
-
if (viewport.width !== void 0) parts.push(`width=${viewport.width}`);
|
|
46
|
-
if (viewport.initialScale !== void 0) parts.push(`initial-scale=${viewport.initialScale}`);
|
|
47
|
-
if (viewport.maximumScale !== void 0) parts.push(`maximum-scale=${viewport.maximumScale}`);
|
|
48
|
-
if (viewport.userScalable !== void 0) parts.push(`user-scalable=${viewport.userScalable ? "yes" : "no"}`);
|
|
49
|
-
if (parts.length) tags.push({ tag: "meta", name: "viewport", content: parts.join(", ") });
|
|
50
|
-
if (viewport.themeColor) tags.push({
|
|
51
|
-
tag: "meta",
|
|
52
|
-
name: "theme-color",
|
|
53
|
-
content: viewport.themeColor
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
return tags;
|
|
57
|
-
}
|
|
58
|
-
function buildHeadNodes(metadata, viewport) {
|
|
59
|
-
const tags = collectTags(metadata, viewport);
|
|
60
|
-
return /* @__PURE__ */ jsx(Fragment, { children: tags.map((t, i) => {
|
|
61
|
-
if (t.tag === "title") return /* @__PURE__ */ jsx("title", { children: t.children }, i);
|
|
62
|
-
if (t.tag === "link") return /* @__PURE__ */ jsx("link", { rel: t.rel, href: t.href, hrefLang: t.hrefLang }, i);
|
|
63
|
-
return /* @__PURE__ */ jsx("meta", { name: t.name, property: t.property, content: t.content }, i);
|
|
64
|
-
}) });
|
|
65
|
-
}
|
|
66
|
-
export {
|
|
67
|
-
buildHeadNodes
|
|
68
|
-
};
|
|
1
|
+
import{Fragment as f,jsx as s}from"react/jsx-runtime";function p(t,n){let e=[];t.title&&e.push({tag:"title",children:t.title}),t.description&&e.push({tag:"meta",name:"description",content:t.description}),t.keywords?.length&&e.push({tag:"meta",name:"keywords",content:t.keywords.join(", ")});let i=t.og?.title??t.title;i&&e.push({tag:"meta",property:"og:title",content:i});let o=t.og?.description??t.description;o&&e.push({tag:"meta",property:"og:description",content:o}),t.og?.image&&e.push({tag:"meta",property:"og:image",content:t.og.image}),t.og?.type&&e.push({tag:"meta",property:"og:type",content:t.og.type}),t.og?.url&&e.push({tag:"meta",property:"og:url",content:t.og.url});let c=t.twitter?.title??t.title;c&&e.push({tag:"meta",name:"twitter:title",content:c});let g=t.twitter?.description??t.description;if(g&&e.push({tag:"meta",name:"twitter:description",content:g}),t.twitter?.card&&e.push({tag:"meta",name:"twitter:card",content:t.twitter.card}),t.twitter?.image&&e.push({tag:"meta",name:"twitter:image",content:t.twitter.image}),t.twitter?.creator&&e.push({tag:"meta",name:"twitter:creator",content:t.twitter.creator}),t.canonical&&e.push({tag:"link",rel:"canonical",href:t.canonical}),t.robots&&e.push({tag:"meta",name:"robots",content:t.robots}),t.alternates)for(let[r,l]of Object.entries(t.alternates))e.push({tag:"link",rel:"alternate",href:l,hrefLang:r});if(n){let r=[];n.width!==void 0&&r.push(`width=${n.width}`),n.initialScale!==void 0&&r.push(`initial-scale=${n.initialScale}`),n.maximumScale!==void 0&&r.push(`maximum-scale=${n.maximumScale}`),n.userScalable!==void 0&&r.push(`user-scalable=${n.userScalable?"yes":"no"}`),r.length&&e.push({tag:"meta",name:"viewport",content:r.join(", ")}),n.themeColor&&e.push({tag:"meta",name:"theme-color",content:n.themeColor})}return e}function h(t,n){let e=p(t,n);return s(f,{children:e.map((i,o)=>i.tag==="title"?s("title",{children:i.children},o):i.tag==="link"?s("link",{rel:i.rel,href:i.href,hrefLang:i.hrefLang},o):s("meta",{name:i.name,property:i.property,content:i.content},o))})}export{h as buildHeadNodes};
|
|
69
2
|
//# sourceMappingURL=head.js.map
|
package/dist/runtime/head.js.map
CHANGED
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/runtime/head.tsx"],
|
|
4
4
|
"sourcesContent": ["import {Metadata, Viewport} from \"../types\";\nimport {ReactNode} from \"react\";\n\ntype MetaTag =\n | { tag: 'title'; children: string }\n | { tag: 'meta'; name?: string; property?: string; content: string }\n | { tag: 'link'; rel: string; href: string; hrefLang?: string }\n\nfunction collectTags(metadata: Metadata, viewport?: Viewport): MetaTag[] {\n const tags: MetaTag[] = []\n\n if (metadata.title)\n tags.push({tag: 'title', children: metadata.title})\n if (metadata.description)\n tags.push({tag: 'meta', name: 'description', content: metadata.description})\n if (metadata.keywords?.length)\n tags.push({tag: 'meta', name: 'keywords', content: metadata.keywords.join(', ')})\n\n const ogTitle = metadata.og?.title ?? metadata.title\n if (ogTitle) tags.push({tag: 'meta', property: 'og:title', content: ogTitle})\n const ogDesc = metadata.og?.description ?? metadata.description\n if (ogDesc) tags.push({tag: 'meta', property: 'og:description', content: ogDesc})\n if (metadata.og?.image) tags.push({tag: 'meta', property: 'og:image', content: metadata.og.image})\n if (metadata.og?.type) tags.push({tag: 'meta', property: 'og:type', content: metadata.og.type})\n if (metadata.og?.url) tags.push({tag: 'meta', property: 'og:url', content: metadata.og.url})\n\n const twTitle = metadata.twitter?.title ?? metadata.title\n if (twTitle) tags.push({tag: 'meta', name: 'twitter:title', content: twTitle})\n const twDesc = metadata.twitter?.description ?? metadata.description\n if (twDesc) tags.push({tag: 'meta', name: 'twitter:description', content: twDesc})\n if (metadata.twitter?.card) tags.push({\n tag: 'meta', name: 'twitter:card', content:\n metadata.twitter.card\n })\n if (metadata.twitter?.image) tags.push({\n tag: 'meta', name: 'twitter:image', content:\n metadata.twitter.image\n })\n if (metadata.twitter?.creator) tags.push({\n tag: 'meta', name: 'twitter:creator', content:\n metadata.twitter.creator\n })\n\n if (metadata.canonical) tags.push({tag: 'link', rel: 'canonical', href: metadata.canonical})\n if (metadata.robots) tags.push({tag: 'meta', name: 'robots', content: metadata.robots})\n if (metadata.alternates) {\n for (const [lang, href] of Object.entries(metadata.alternates))\n tags.push({tag: 'link', rel: 'alternate', href, hrefLang: lang})\n }\n\n if (viewport) {\n const parts: string[] = []\n if (viewport.width !== undefined) parts.push(`width=${viewport.width}`)\n if (viewport.initialScale !== undefined) parts.push(`initial-scale=${viewport.initialScale}`)\n if (viewport.maximumScale !== undefined) parts.push(`maximum-scale=${viewport.maximumScale}`)\n if (viewport.userScalable !== undefined) parts.push(`user-scalable=${viewport.userScalable ? 'yes' :\n 'no'}`)\n if (parts.length) tags.push({tag: 'meta', name: 'viewport', content: parts.join(', ')})\n if (viewport.themeColor) tags.push({\n tag: 'meta', name: 'theme-color', content: viewport.themeColor\n })\n }\n\n return tags\n}\n\nexport function buildHeadNodes(metadata: Metadata, viewport?: Viewport): ReactNode {\n const tags = collectTags(metadata, viewport)\n\n return <>\n {tags.map((t, i) => {\n if (t.tag === 'title') return <title key={i}>{t.children}</title>\n if (t.tag === 'link') return <link key={i} rel={t.rel} href={t.href} hrefLang={t.hrefLang}/>\n return <meta key={i} name={t.name} property={t.property} content={t.content}/>\n })}\n </>\n}"],
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": []
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["Fragment", "jsx", "collectTags", "metadata", "viewport", "tags", "ogTitle", "ogDesc", "twTitle", "twDesc", "lang", "href", "parts", "buildHeadNodes", "t", "i"]
|
|
7
7
|
}
|
package/dist/runtime/index.d.ts
CHANGED
|
@@ -6,5 +6,6 @@ export type { RouteHandler, RouteResult } from './api-context';
|
|
|
6
6
|
export { getCookie, setCookie, deleteCookie } from '../utils/cookies';
|
|
7
7
|
export type { CookieOptions } from '../utils/cookies';
|
|
8
8
|
export { json, text, redirect } from '../utils/response';
|
|
9
|
+
export type { JsonResponse } from '../utils/response';
|
|
9
10
|
export { $fetch, FetchError } from './fetch';
|
|
10
11
|
export type { ApiRoutes, FetchOptions } from './fetch';
|
package/dist/runtime/index.js
CHANGED
|
@@ -1,368 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
import { useCallback, useContext, useEffect, useRef, useState } from "react";
|
|
3
|
-
import { RouterContext as RouterContext2 } from "virtual:devix/context";
|
|
4
|
-
import { getDefaultErrorPage, loadErrorPage, matchClientRoute } from "virtual:devix/client-routes";
|
|
5
|
-
|
|
6
|
-
// src/runtime/head.tsx
|
|
7
|
-
import { Fragment, jsx } from "react/jsx-runtime";
|
|
8
|
-
function collectTags(metadata, viewport) {
|
|
9
|
-
const tags = [];
|
|
10
|
-
if (metadata.title)
|
|
11
|
-
tags.push({ tag: "title", children: metadata.title });
|
|
12
|
-
if (metadata.description)
|
|
13
|
-
tags.push({ tag: "meta", name: "description", content: metadata.description });
|
|
14
|
-
if (metadata.keywords?.length)
|
|
15
|
-
tags.push({ tag: "meta", name: "keywords", content: metadata.keywords.join(", ") });
|
|
16
|
-
const ogTitle = metadata.og?.title ?? metadata.title;
|
|
17
|
-
if (ogTitle) tags.push({ tag: "meta", property: "og:title", content: ogTitle });
|
|
18
|
-
const ogDesc = metadata.og?.description ?? metadata.description;
|
|
19
|
-
if (ogDesc) tags.push({ tag: "meta", property: "og:description", content: ogDesc });
|
|
20
|
-
if (metadata.og?.image) tags.push({ tag: "meta", property: "og:image", content: metadata.og.image });
|
|
21
|
-
if (metadata.og?.type) tags.push({ tag: "meta", property: "og:type", content: metadata.og.type });
|
|
22
|
-
if (metadata.og?.url) tags.push({ tag: "meta", property: "og:url", content: metadata.og.url });
|
|
23
|
-
const twTitle = metadata.twitter?.title ?? metadata.title;
|
|
24
|
-
if (twTitle) tags.push({ tag: "meta", name: "twitter:title", content: twTitle });
|
|
25
|
-
const twDesc = metadata.twitter?.description ?? metadata.description;
|
|
26
|
-
if (twDesc) tags.push({ tag: "meta", name: "twitter:description", content: twDesc });
|
|
27
|
-
if (metadata.twitter?.card) tags.push({
|
|
28
|
-
tag: "meta",
|
|
29
|
-
name: "twitter:card",
|
|
30
|
-
content: metadata.twitter.card
|
|
31
|
-
});
|
|
32
|
-
if (metadata.twitter?.image) tags.push({
|
|
33
|
-
tag: "meta",
|
|
34
|
-
name: "twitter:image",
|
|
35
|
-
content: metadata.twitter.image
|
|
36
|
-
});
|
|
37
|
-
if (metadata.twitter?.creator) tags.push({
|
|
38
|
-
tag: "meta",
|
|
39
|
-
name: "twitter:creator",
|
|
40
|
-
content: metadata.twitter.creator
|
|
41
|
-
});
|
|
42
|
-
if (metadata.canonical) tags.push({ tag: "link", rel: "canonical", href: metadata.canonical });
|
|
43
|
-
if (metadata.robots) tags.push({ tag: "meta", name: "robots", content: metadata.robots });
|
|
44
|
-
if (metadata.alternates) {
|
|
45
|
-
for (const [lang, href] of Object.entries(metadata.alternates))
|
|
46
|
-
tags.push({ tag: "link", rel: "alternate", href, hrefLang: lang });
|
|
47
|
-
}
|
|
48
|
-
if (viewport) {
|
|
49
|
-
const parts = [];
|
|
50
|
-
if (viewport.width !== void 0) parts.push(`width=${viewport.width}`);
|
|
51
|
-
if (viewport.initialScale !== void 0) parts.push(`initial-scale=${viewport.initialScale}`);
|
|
52
|
-
if (viewport.maximumScale !== void 0) parts.push(`maximum-scale=${viewport.maximumScale}`);
|
|
53
|
-
if (viewport.userScalable !== void 0) parts.push(`user-scalable=${viewport.userScalable ? "yes" : "no"}`);
|
|
54
|
-
if (parts.length) tags.push({ tag: "meta", name: "viewport", content: parts.join(", ") });
|
|
55
|
-
if (viewport.themeColor) tags.push({
|
|
56
|
-
tag: "meta",
|
|
57
|
-
name: "theme-color",
|
|
58
|
-
content: viewport.themeColor
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
return tags;
|
|
62
|
-
}
|
|
63
|
-
function buildHeadNodes(metadata, viewport) {
|
|
64
|
-
const tags = collectTags(metadata, viewport);
|
|
65
|
-
return /* @__PURE__ */ jsx(Fragment, { children: tags.map((t, i) => {
|
|
66
|
-
if (t.tag === "title") return /* @__PURE__ */ jsx("title", { children: t.children }, i);
|
|
67
|
-
if (t.tag === "link") return /* @__PURE__ */ jsx("link", { rel: t.rel, href: t.href, hrefLang: t.hrefLang }, i);
|
|
68
|
-
return /* @__PURE__ */ jsx("meta", { name: t.name, property: t.property, content: t.content }, i);
|
|
69
|
-
}) });
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// src/runtime/context.tsx
|
|
73
|
-
import { createContext } from "react";
|
|
74
|
-
var g = globalThis;
|
|
75
|
-
g.__devix_RouterContext__ ??= createContext(null);
|
|
76
|
-
var RouterContext = g.__devix_RouterContext__;
|
|
77
|
-
g.__devix_PageMetaContext__ ??= createContext(null);
|
|
78
|
-
g.__devix_RouteDataContext__ ??= createContext(null);
|
|
79
|
-
var PageMetaContext = g.__devix_PageMetaContext__;
|
|
80
|
-
var RouteDataContext = g.__devix_RouteDataContext__;
|
|
81
|
-
|
|
82
|
-
// src/runtime/error-boundary.tsx
|
|
83
|
-
import { Component } from "react";
|
|
84
|
-
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
85
|
-
var DevixErrorBoundary = class extends Component {
|
|
86
|
-
state = { error: null };
|
|
87
|
-
static getDerivedStateFromError(err) {
|
|
88
|
-
if (err instanceof DevixError) {
|
|
89
|
-
return {
|
|
90
|
-
error: { statusCode: err.statusCode, message: err.message }
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
return {
|
|
94
|
-
error: { statusCode: 500, message: err instanceof Error ? err.message : "Unknown error" }
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
render() {
|
|
98
|
-
if (this.state.error && this.props.ErrorPage) {
|
|
99
|
-
return /* @__PURE__ */ jsx2(this.props.ErrorPage, { ...this.state.error });
|
|
100
|
-
}
|
|
101
|
-
if (this.state.error) {
|
|
102
|
-
return /* @__PURE__ */ jsx2("h1", { children: this.state.error.statusCode });
|
|
103
|
-
}
|
|
104
|
-
return this.props.children;
|
|
105
|
-
}
|
|
106
|
-
};
|
|
107
|
-
var DevixError = class extends Error {
|
|
108
|
-
statusCode;
|
|
109
|
-
constructor(statusCode, message) {
|
|
110
|
-
super(message);
|
|
111
|
-
this.statusCode = statusCode;
|
|
112
|
-
}
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
// src/runtime/router-provider.tsx
|
|
116
|
-
import { jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
117
|
-
function useRouter() {
|
|
118
|
-
return useContext(RouterContext2);
|
|
119
|
-
}
|
|
120
|
-
function useNavigate() {
|
|
121
|
-
const ctx = useContext(RouterContext2);
|
|
122
|
-
if (!ctx) throw new Error("useNavigate must be used within a RouterProvider");
|
|
123
|
-
return ctx.navigate;
|
|
124
|
-
}
|
|
125
|
-
function useParams() {
|
|
126
|
-
const ctx = useContext(RouteDataContext);
|
|
127
|
-
if (!ctx) throw new Error("useParams must be used within a route or layout");
|
|
128
|
-
return ctx.params;
|
|
129
|
-
}
|
|
130
|
-
function useLoaderData() {
|
|
131
|
-
const ctx = useContext(RouteDataContext);
|
|
132
|
-
if (!ctx) throw new Error("useLoaderData must be used within a route or layout");
|
|
133
|
-
return ctx.loaderData;
|
|
134
|
-
}
|
|
135
|
-
function RouterProvider({
|
|
136
|
-
initialData,
|
|
137
|
-
initialParams,
|
|
138
|
-
initialPage,
|
|
139
|
-
initialLayouts = [],
|
|
140
|
-
initialLayoutsData = [],
|
|
141
|
-
initialMeta,
|
|
142
|
-
initialViewport,
|
|
143
|
-
initialError,
|
|
144
|
-
initialErrorPage,
|
|
145
|
-
clientEntry
|
|
146
|
-
}) {
|
|
147
|
-
const [state, setState] = useState({
|
|
148
|
-
pathname: window.location.pathname,
|
|
149
|
-
params: initialParams,
|
|
150
|
-
loaderData: initialData,
|
|
151
|
-
layoutsData: initialLayoutsData,
|
|
152
|
-
Page: initialPage,
|
|
153
|
-
layouts: initialLayouts,
|
|
154
|
-
metadata: initialMeta ?? null,
|
|
155
|
-
viewport: initialViewport,
|
|
156
|
-
pendingError: initialError,
|
|
157
|
-
ErrorPage: initialErrorPage
|
|
158
|
-
});
|
|
159
|
-
const navigatingRef = useRef(null);
|
|
160
|
-
const [isNavigating, setIsNavigating] = useState(false);
|
|
161
|
-
const loadRoute = useCallback(async (to, controller) => {
|
|
162
|
-
const pathname = to.split("?")[0];
|
|
163
|
-
const matched = matchClientRoute(pathname);
|
|
164
|
-
if (!matched) {
|
|
165
|
-
const ErrorPage = await loadErrorPage() ?? getDefaultErrorPage();
|
|
166
|
-
setState((prev) => ({
|
|
167
|
-
...prev,
|
|
168
|
-
pathname,
|
|
169
|
-
pendingError: { statusCode: 404, message: "Not found" },
|
|
170
|
-
ErrorPage: ErrorPage ?? void 0
|
|
171
|
-
}));
|
|
172
|
-
return;
|
|
173
|
-
}
|
|
174
|
-
const [pageMod, ...layoutMods] = await Promise.all([
|
|
175
|
-
matched.load(),
|
|
176
|
-
...matched.loadLayouts.map((l) => l())
|
|
177
|
-
]);
|
|
178
|
-
if (controller.signal.aborted) return;
|
|
179
|
-
if (!pageMod.default) return;
|
|
180
|
-
const dataRes = await fetch(`/_data${to}`, {
|
|
181
|
-
headers: { Accept: "application/json" },
|
|
182
|
-
signal: controller.signal
|
|
183
|
-
});
|
|
184
|
-
if (controller.signal.aborted) return;
|
|
185
|
-
if (!dataRes.ok) {
|
|
186
|
-
if (dataRes.status === 404) {
|
|
187
|
-
window.location.href = to;
|
|
188
|
-
return;
|
|
189
|
-
}
|
|
190
|
-
console.error(`/_data${to} returned ${dataRes.status}`);
|
|
191
|
-
return;
|
|
192
|
-
}
|
|
193
|
-
const data = await dataRes.json();
|
|
194
|
-
window.scrollTo(0, 0);
|
|
195
|
-
setState({
|
|
196
|
-
pathname,
|
|
197
|
-
params: data.params ?? {},
|
|
198
|
-
loaderData: data.loaderData,
|
|
199
|
-
layoutsData: (data.layouts ?? []).map((l) => l.loaderData),
|
|
200
|
-
Page: pageMod.default,
|
|
201
|
-
layouts: layoutMods.map((m) => m.default),
|
|
202
|
-
metadata: data.metadata ?? null,
|
|
203
|
-
viewport: data.viewport
|
|
204
|
-
});
|
|
205
|
-
}, []);
|
|
206
|
-
const navigate = useCallback(async (to) => {
|
|
207
|
-
navigatingRef.current?.abort();
|
|
208
|
-
const controller = new AbortController();
|
|
209
|
-
navigatingRef.current = controller;
|
|
210
|
-
setIsNavigating(true);
|
|
211
|
-
try {
|
|
212
|
-
window.history.pushState(null, "", to);
|
|
213
|
-
await loadRoute(to, controller);
|
|
214
|
-
} finally {
|
|
215
|
-
if (!controller.signal.aborted) setIsNavigating(false);
|
|
216
|
-
}
|
|
217
|
-
}, [loadRoute]);
|
|
218
|
-
useEffect(() => {
|
|
219
|
-
const handlePop = () => {
|
|
220
|
-
navigatingRef.current?.abort();
|
|
221
|
-
const controller = new AbortController();
|
|
222
|
-
navigatingRef.current = controller;
|
|
223
|
-
const to = window.location.pathname + window.location.search;
|
|
224
|
-
loadRoute(to, controller).catch((err) => {
|
|
225
|
-
if (err.name !== "AbortError") console.error("[router] popstate error:", err);
|
|
226
|
-
});
|
|
227
|
-
};
|
|
228
|
-
window.addEventListener("popstate", handlePop);
|
|
229
|
-
return () => window.removeEventListener("popstate", handlePop);
|
|
230
|
-
}, [loadRoute]);
|
|
231
|
-
let content;
|
|
232
|
-
if (state.pendingError) {
|
|
233
|
-
content = state.ErrorPage ? /* @__PURE__ */ jsx3(state.ErrorPage, { ...state.pendingError }) : /* @__PURE__ */ jsx3("h1", { children: state.pendingError.statusCode });
|
|
234
|
-
} else {
|
|
235
|
-
let tree = /* @__PURE__ */ jsx3(RouteDataContext, { value: { loaderData: state.loaderData, params: state.params }, children: /* @__PURE__ */ jsx3(state.Page, { data: state.loaderData, params: state.params, url: state.pathname }) });
|
|
236
|
-
for (let i = state.layouts.length - 1; i >= 0; i--) {
|
|
237
|
-
const Layout = state.layouts[i];
|
|
238
|
-
const layoutData = state.layoutsData[i];
|
|
239
|
-
tree = /* @__PURE__ */ jsx3(RouteDataContext, { value: { loaderData: layoutData, params: state.params }, children: /* @__PURE__ */ jsx3(Layout, { data: layoutData, params: state.params, children: tree }) });
|
|
240
|
-
}
|
|
241
|
-
content = /* @__PURE__ */ jsx3(DevixErrorBoundary, { ErrorPage: state.ErrorPage, children: tree }, state.pathname);
|
|
242
|
-
}
|
|
243
|
-
return /* @__PURE__ */ jsxs(PageMetaContext, { value: {
|
|
244
|
-
metadata: state.metadata,
|
|
245
|
-
viewport: state.viewport,
|
|
246
|
-
clientEntry
|
|
247
|
-
}, children: [
|
|
248
|
-
state.metadata && buildHeadNodes(state.metadata, state.viewport),
|
|
249
|
-
/* @__PURE__ */ jsx3(RouterContext2, { value: { ...state, isNavigating, navigate }, children: content })
|
|
250
|
-
] });
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
// src/runtime/link.tsx
|
|
254
|
-
import { useCallback as useCallback2, useContext as useContext2 } from "react";
|
|
255
|
-
import { matchClientRoute as matchClientRoute2 } from "virtual:devix/client-routes";
|
|
256
|
-
import { RouterContext as RouterContext3 } from "virtual:devix/context";
|
|
257
|
-
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
258
|
-
function resolveHref(href) {
|
|
259
|
-
if (href.startsWith("/") || href.startsWith("http")) return href;
|
|
260
|
-
const base = window.location.pathname.endsWith("/") ? window.location.href : window.location.href + "/";
|
|
261
|
-
const resolved = new URL(href, base).pathname;
|
|
262
|
-
return resolved.length > 1 ? resolved.replace(/\/$/, "") : resolved;
|
|
263
|
-
}
|
|
264
|
-
function Link({ href, prefetch = false, viewTransition = false, children, ...props }) {
|
|
265
|
-
const router = useContext2(RouterContext3);
|
|
266
|
-
const handleMouseEnter = useCallback2(() => {
|
|
267
|
-
if (!prefetch) return;
|
|
268
|
-
const resolved = resolveHref(href);
|
|
269
|
-
const pathname = resolved.split("?")[0];
|
|
270
|
-
const matched = matchClientRoute2(pathname);
|
|
271
|
-
if (matched) {
|
|
272
|
-
matched.load().catch(() => {
|
|
273
|
-
});
|
|
274
|
-
fetch(`/_data${resolved}`, { headers: { Accept: "application/json" } }).catch(() => {
|
|
275
|
-
});
|
|
276
|
-
}
|
|
277
|
-
}, [href, prefetch]);
|
|
278
|
-
const handleClick = (e) => {
|
|
279
|
-
if (!router) return;
|
|
280
|
-
if (!e.ctrlKey && !e.metaKey && !e.shiftKey && e.button === 0) {
|
|
281
|
-
e.preventDefault();
|
|
282
|
-
const resolved = resolveHref(href);
|
|
283
|
-
if (viewTransition && typeof document.startViewTransition === "function") {
|
|
284
|
-
document.startViewTransition(() => router.navigate(resolved));
|
|
285
|
-
} else {
|
|
286
|
-
router.navigate(resolved);
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
};
|
|
290
|
-
return /* @__PURE__ */ jsx4("a", { href, onClick: handleClick, onMouseEnter: handleMouseEnter, ...props, children });
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
// src/utils/cookies.ts
|
|
294
|
-
function getCookie(req, name) {
|
|
295
|
-
const header = req.headers.get("cookie");
|
|
296
|
-
if (!header) return void 0;
|
|
297
|
-
for (const part of header.split(";")) {
|
|
298
|
-
const [key, ...rest] = part.trim().split("=");
|
|
299
|
-
if (key.trim() === name) return decodeURIComponent(rest.join("="));
|
|
300
|
-
}
|
|
301
|
-
return void 0;
|
|
302
|
-
}
|
|
303
|
-
function setCookie(headers, name, value, options = {}) {
|
|
304
|
-
let cookie = `${name}=${encodeURIComponent(value)}; Path=${options.path ?? "/"}`;
|
|
305
|
-
if (options.domain) cookie += `; Domain=${options.domain}`;
|
|
306
|
-
if (options.maxAge !== void 0) cookie += `; Max-Age=${options.maxAge}`;
|
|
307
|
-
if (options.expires) cookie += `; Expires=${options.expires.toUTCString()}`;
|
|
308
|
-
if (options.httpOnly) cookie += `; HttpOnly`;
|
|
309
|
-
if (options.secure) cookie += `; Secure`;
|
|
310
|
-
if (options.sameSite) cookie += `; SameSite=${options.sameSite}`;
|
|
311
|
-
headers.append("Set-Cookie", cookie);
|
|
312
|
-
}
|
|
313
|
-
function deleteCookie(headers, name, options = {}) {
|
|
314
|
-
setCookie(headers, name, "", { ...options, maxAge: 0, expires: /* @__PURE__ */ new Date(0) });
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
// src/utils/response.ts
|
|
318
|
-
var json = (data, status = 200) => Response.json(data, { status });
|
|
319
|
-
var text = (body, status = 200) => new Response(body, { status, headers: { "Content-Type": "text/plain; charset=utf-8" } });
|
|
320
|
-
var redirect = (url, status = 302) => new Response(null, { status, headers: { Location: url } });
|
|
321
|
-
|
|
322
|
-
// src/runtime/fetch.ts
|
|
323
|
-
var FetchError = class extends Error {
|
|
324
|
-
constructor(status, statusText, response) {
|
|
325
|
-
super(`HTTP ${status}: ${statusText}`);
|
|
326
|
-
this.status = status;
|
|
327
|
-
this.statusText = statusText;
|
|
328
|
-
this.response = response;
|
|
329
|
-
this.name = "FetchError";
|
|
330
|
-
}
|
|
331
|
-
};
|
|
332
|
-
async function $fetch(path, options) {
|
|
333
|
-
const method = options?.method ?? "GET";
|
|
334
|
-
const headers = new Headers(options?.headers);
|
|
335
|
-
let body;
|
|
336
|
-
if (options?.body !== void 0) {
|
|
337
|
-
body = JSON.stringify(options.body);
|
|
338
|
-
if (!headers.has("Content-Type")) {
|
|
339
|
-
headers.set("Content-Type", "application/json");
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
const response = await fetch(path, { method, headers, body, signal: options?.signal });
|
|
343
|
-
if (!response.ok) {
|
|
344
|
-
throw new FetchError(response.status, response.statusText, response);
|
|
345
|
-
}
|
|
346
|
-
const contentType = response.headers.get("Content-Type") ?? "";
|
|
347
|
-
if (contentType.includes("application/json")) {
|
|
348
|
-
return response.json();
|
|
349
|
-
}
|
|
350
|
-
return response.text();
|
|
351
|
-
}
|
|
352
|
-
export {
|
|
353
|
-
$fetch,
|
|
354
|
-
FetchError,
|
|
355
|
-
Link,
|
|
356
|
-
RouterProvider,
|
|
357
|
-
deleteCookie,
|
|
358
|
-
getCookie,
|
|
359
|
-
json,
|
|
360
|
-
redirect,
|
|
361
|
-
setCookie,
|
|
362
|
-
text,
|
|
363
|
-
useLoaderData,
|
|
364
|
-
useNavigate,
|
|
365
|
-
useParams,
|
|
366
|
-
useRouter
|
|
367
|
-
};
|
|
1
|
+
import{useCallback as N,useContext as k,useEffect as q,useRef as z,useState as O}from"react";import{RouterContext as L}from"virtual:devix/context";import{getDefaultErrorPage as Q,loadErrorPage as X,matchClientRoute as Y}from"virtual:devix/client-routes";import{Fragment as W,jsx as T}from"react/jsx-runtime";function J(e,t){let o=[];e.title&&o.push({tag:"title",children:e.title}),e.description&&o.push({tag:"meta",name:"description",content:e.description}),e.keywords?.length&&o.push({tag:"meta",name:"keywords",content:e.keywords.join(", ")});let r=e.og?.title??e.title;r&&o.push({tag:"meta",property:"og:title",content:r});let a=e.og?.description??e.description;a&&o.push({tag:"meta",property:"og:description",content:a}),e.og?.image&&o.push({tag:"meta",property:"og:image",content:e.og.image}),e.og?.type&&o.push({tag:"meta",property:"og:type",content:e.og.type}),e.og?.url&&o.push({tag:"meta",property:"og:url",content:e.og.url});let s=e.twitter?.title??e.title;s&&o.push({tag:"meta",name:"twitter:title",content:s});let g=e.twitter?.description??e.description;if(g&&o.push({tag:"meta",name:"twitter:description",content:g}),e.twitter?.card&&o.push({tag:"meta",name:"twitter:card",content:e.twitter.card}),e.twitter?.image&&o.push({tag:"meta",name:"twitter:image",content:e.twitter.image}),e.twitter?.creator&&o.push({tag:"meta",name:"twitter:creator",content:e.twitter.creator}),e.canonical&&o.push({tag:"link",rel:"canonical",href:e.canonical}),e.robots&&o.push({tag:"meta",name:"robots",content:e.robots}),e.alternates)for(let[l,u]of Object.entries(e.alternates))o.push({tag:"link",rel:"alternate",href:u,hrefLang:l});if(t){let l=[];t.width!==void 0&&l.push(`width=${t.width}`),t.initialScale!==void 0&&l.push(`initial-scale=${t.initialScale}`),t.maximumScale!==void 0&&l.push(`maximum-scale=${t.maximumScale}`),t.userScalable!==void 0&&l.push(`user-scalable=${t.userScalable?"yes":"no"}`),l.length&&o.push({tag:"meta",name:"viewport",content:l.join(", ")}),t.themeColor&&o.push({tag:"meta",name:"theme-color",content:t.themeColor})}return o}function H(e,t){let o=J(e,t);return T(W,{children:o.map((r,a)=>r.tag==="title"?T("title",{children:r.children},a):r.tag==="link"?T("link",{rel:r.rel,href:r.href,hrefLang:r.hrefLang},a):T("meta",{name:r.name,property:r.property,content:r.content},a))})}import{createContext as v}from"react";var y=globalThis;y.__devix_RouterContext__??=v(null);var Re=y.__devix_RouterContext__;y.__devix_PageMetaContext__??=v(null);y.__devix_RouteDataContext__??=v(null);var V=y.__devix_PageMetaContext__,w=y.__devix_RouteDataContext__;import{Component as B}from"react";import{jsx as $}from"react/jsx-runtime";var E=class extends B{state={error:null};static getDerivedStateFromError(t){return t instanceof D?{error:{statusCode:t.statusCode,message:t.message}}:{error:{statusCode:500,message:t instanceof Error?t.message:"Unknown error"}}}render(){return this.state.error&&this.props.ErrorPage?$(this.props.ErrorPage,{...this.state.error}):this.state.error?$("h1",{children:this.state.error.statusCode}):this.props.children}},D=class extends Error{statusCode;constructor(t,o){super(o),this.statusCode=t}};import{jsx as d,jsxs as ne}from"react/jsx-runtime";function Z(){return k(L)}function ee(){let e=k(L);if(!e)throw new Error("useNavigate must be used within a RouterProvider");return e.navigate}function te(){let e=k(w);if(!e)throw new Error("useParams must be used within a route or layout");return e.params}function oe(){let e=k(w);if(!e)throw new Error("useLoaderData must be used within a route or layout");return e.loaderData}function re({initialData:e,initialParams:t,initialPage:o,initialLayouts:r=[],initialLayoutsData:a=[],initialMeta:s,initialViewport:g,initialError:l,initialErrorPage:u,clientEntry:h}){let[n,_]=O({pathname:window.location.pathname,params:t,loaderData:e,layoutsData:a,Page:o,layouts:r,metadata:s??null,viewport:g,pendingError:l,ErrorPage:u}),P=z(null),[F,S]=O(!1),C=N(async(p,i)=>{let f=p.split("?")[0],c=Y(f);if(!c){let m=await X()??Q();_(G=>({...G,pathname:f,pendingError:{statusCode:404,message:"Not found"},ErrorPage:m??void 0}));return}let[A,...U]=await Promise.all([c.load(),...c.loadLayouts.map(m=>m())]);if(i.signal.aborted||!A.default)return;let R=await fetch(`/_data${p}`,{headers:{Accept:"application/json"},signal:i.signal});if(i.signal.aborted)return;if(!R.ok){if(R.status===404){window.location.href=p;return}console.error(`/_data${p} returned ${R.status}`);return}let x=await R.json();window.scrollTo(0,0),_({pathname:f,params:x.params??{},loaderData:x.loaderData,layoutsData:(x.layouts??[]).map(m=>m.loaderData),Page:A.default,layouts:U.map(m=>m.default),metadata:x.metadata??null,viewport:x.viewport})},[]),K=N(async p=>{P.current?.abort();let i=new AbortController;P.current=i,S(!0);try{window.history.pushState(null,"",p),await C(p,i)}finally{i.signal.aborted||S(!1)}},[C]);q(()=>{let p=()=>{P.current?.abort();let i=new AbortController;P.current=i;let f=window.location.pathname+window.location.search;C(f,i).catch(c=>{c.name!=="AbortError"&&console.error("[router] popstate error:",c)})};return window.addEventListener("popstate",p),()=>window.removeEventListener("popstate",p)},[C]);let b;if(n.pendingError)b=n.ErrorPage?d(n.ErrorPage,{...n.pendingError}):d("h1",{children:n.pendingError.statusCode});else{let p=d(w,{value:{loaderData:n.loaderData,params:n.params},children:d(n.Page,{data:n.loaderData,params:n.params,url:n.pathname})});for(let i=n.layouts.length-1;i>=0;i--){let f=n.layouts[i],c=n.layoutsData[i];p=d(w,{value:{loaderData:c,params:n.params},children:d(f,{data:c,params:n.params,children:p})})}b=d(E,{ErrorPage:n.ErrorPage,children:p},n.pathname)}return ne(V,{value:{metadata:n.metadata,viewport:n.viewport,clientEntry:h},children:[n.metadata&&H(n.metadata,n.viewport),d(L,{value:{...n,isNavigating:F,navigate:K},children:b})]})}import{useCallback as ae,useContext as se}from"react";import{matchClientRoute as ie}from"virtual:devix/client-routes";import{RouterContext as pe}from"virtual:devix/context";import{jsx as le}from"react/jsx-runtime";function I(e){if(e.startsWith("/")||e.startsWith("http"))return e;let t=window.location.pathname.endsWith("/")?window.location.href:window.location.href+"/",o=new URL(e,t).pathname;return o.length>1?o.replace(/\/$/,""):o}function ue({href:e,prefetch:t=!1,viewTransition:o=!1,children:r,...a}){let s=se(pe),g=ae(()=>{if(!t)return;let u=I(e),h=u.split("?")[0],n=ie(h);n&&(n.load().catch(()=>{}),fetch(`/_data${u}`,{headers:{Accept:"application/json"}}).catch(()=>{}))},[e,t]);return le("a",{href:e,onClick:u=>{if(s&&!u.ctrlKey&&!u.metaKey&&!u.shiftKey&&u.button===0){u.preventDefault();let h=I(e);o&&typeof document.startViewTransition=="function"?document.startViewTransition(()=>s.navigate(h)):s.navigate(h)}},onMouseEnter:g,...a,children:r})}function ce(e,t){let o=e.headers.get("cookie");if(o)for(let r of o.split(";")){let[a,...s]=r.trim().split("=");if(a.trim()===t)return decodeURIComponent(s.join("="))}}function j(e,t,o,r={}){let a=`${t}=${encodeURIComponent(o)}; Path=${r.path??"/"}`;r.domain&&(a+=`; Domain=${r.domain}`),r.maxAge!==void 0&&(a+=`; Max-Age=${r.maxAge}`),r.expires&&(a+=`; Expires=${r.expires.toUTCString()}`),r.httpOnly&&(a+="; HttpOnly"),r.secure&&(a+="; Secure"),r.sameSite&&(a+=`; SameSite=${r.sameSite}`),e.append("Set-Cookie",a)}function de(e,t,o={}){j(e,t,"",{...o,maxAge:0,expires:new Date(0)})}var ge=(e,t=200)=>Response.json(e,{status:t}),fe=(e,t=200)=>new Response(e,{status:t,headers:{"Content-Type":"text/plain; charset=utf-8"}}),me=(e,t=302)=>new Response(null,{status:t,headers:{Location:e}});var M=class extends Error{constructor(o,r,a){super(`HTTP ${o}: ${r}`);this.status=o;this.statusText=r;this.response=a;this.name="FetchError"}};async function he(e,t){let o=t?.method??"GET",r=new Headers(t?.headers),a;t?.body!==void 0&&(a=JSON.stringify(t.body),r.has("Content-Type")||r.set("Content-Type","application/json"));let s=await fetch(e,{method:o,headers:r,body:a,signal:t?.signal});if(!s.ok)throw new M(s.status,s.statusText,s);return(s.headers.get("Content-Type")??"").includes("application/json")?s.json():s.text()}export{he as $fetch,M as FetchError,ue as Link,re as RouterProvider,de as deleteCookie,ce as getCookie,ge as json,me as redirect,j as setCookie,fe as text,oe as useLoaderData,ee as useNavigate,te as useParams,Z as useRouter};
|
|
368
2
|
//# sourceMappingURL=index.js.map
|