eddev 2.0.0-beta.69 → 2.0.0-beta.71
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/app/entry/boot-admin.js +0 -1
- package/dist/app/lib/routing/components/BrowserRouter.js +1 -1
- package/dist/app/lib/routing/components/Link.js +2 -2
- package/dist/app/lib/routing/loader.js +14 -9
- package/dist/app/lib/routing/utils.js +2 -1
- package/dist/app/server/proxy-wp-admin.js +18 -7
- package/dist/app/server/render-ssr-page.d.ts +8 -0
- package/dist/app/server/render-ssr-page.js +46 -0
- package/dist/app/server/server-context.d.ts +4 -1
- package/dist/app/server/server-context.js +32 -10
- package/dist/app/server/utils/replace-host.d.ts +1 -1
- package/dist/app/server/utils/replace-host.js +11 -2
- package/dist/node/cli/version.d.ts +1 -1
- package/dist/node/cli/version.js +1 -1
- package/dist/node/compiler/vinxi-app.js +26 -6
- package/dist/node/compiler/vinxi-codegen.js +7 -3
- package/dist/node/project/config.d.ts +5 -0
- package/dist/node/project/config.js +5 -2
- package/package.json +1 -1
|
@@ -214,7 +214,7 @@ export function BrowserRouter(props) {
|
|
|
214
214
|
hash: link.hash,
|
|
215
215
|
search: "",
|
|
216
216
|
query: link.query,
|
|
217
|
-
pathname: link.pathname,
|
|
217
|
+
pathname: data.canonical ?? link.pathname,
|
|
218
218
|
view: data.view,
|
|
219
219
|
props: data.viewData?.data ?? {},
|
|
220
220
|
component: lazyComponent,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { forwardRef, useMemo } from "react";
|
|
3
|
-
import { parseURL, resolveURL, withoutTrailingSlash } from "ufo";
|
|
3
|
+
import { parseURL, resolveURL, withoutTrailingSlash, withTrailingSlash } from "ufo";
|
|
4
4
|
import { useIsSSR } from "../hooks/useIsSSR.js";
|
|
5
5
|
import { useRouter } from "../hooks/useRouter.js";
|
|
6
6
|
import { isSameOrigin } from "../utils.js";
|
|
@@ -17,7 +17,7 @@ export const Link = forwardRef(({ preferBack, ...props }, ref) => {
|
|
|
17
17
|
else {
|
|
18
18
|
const router = useRouter();
|
|
19
19
|
const state = useLinkState(props.href ?? "");
|
|
20
|
-
return (_jsx(Comp, { ref: ref, "data-active": state.active ?? undefined, "data-child-active": state.childActive ?? undefined, "data-pending": state.pending ?? undefined, ...props, href: props.href ?? undefined, onMouseEnter: (e) => {
|
|
20
|
+
return (_jsx(Comp, { ref: ref, "data-active": state.active ?? undefined, "data-child-active": state.childActive ?? undefined, "data-pending": state.pending ?? undefined, ...props, href: withTrailingSlash(props.href ?? undefined), onMouseEnter: (e) => {
|
|
21
21
|
if (props.onMouseEnter) {
|
|
22
22
|
props.onMouseEnter(e);
|
|
23
23
|
}
|
|
@@ -56,6 +56,7 @@ export class RouteLoader {
|
|
|
56
56
|
return this.entries.has(cacheKey);
|
|
57
57
|
}
|
|
58
58
|
async loadRouteData(pathname, withAppData = false) {
|
|
59
|
+
pathname = withTrailingSlash(pathname);
|
|
59
60
|
const cacheKey = this.getKey(pathname);
|
|
60
61
|
// Cached value?
|
|
61
62
|
if (this.entries.has(cacheKey))
|
|
@@ -65,9 +66,12 @@ export class RouteLoader {
|
|
|
65
66
|
serverless: env.serverless,
|
|
66
67
|
debug: env.dev,
|
|
67
68
|
});
|
|
68
|
-
const promise = this.fetchImpl(requestUrl
|
|
69
|
-
.then((response) =>
|
|
70
|
-
.
|
|
69
|
+
const promise = this.fetchImpl(requestUrl)
|
|
70
|
+
.then(async (response) => {
|
|
71
|
+
if (response.redirected) {
|
|
72
|
+
return { redirect: response.url };
|
|
73
|
+
}
|
|
74
|
+
let text = await response.text();
|
|
71
75
|
if (this.processProps) {
|
|
72
76
|
text = this.processProps(text);
|
|
73
77
|
}
|
|
@@ -78,14 +82,15 @@ export class RouteLoader {
|
|
|
78
82
|
throw new RouteError(`JSON parse error for route '${pathname}':\n${err?.message}`, 500);
|
|
79
83
|
}
|
|
80
84
|
})
|
|
81
|
-
.then((data) => {
|
|
85
|
+
.then(async (data) => {
|
|
82
86
|
if (data.redirect) {
|
|
83
|
-
const redirect = data.redirect;
|
|
84
|
-
data = this.loadRouteData(redirect)
|
|
85
|
-
|
|
86
|
-
return data;
|
|
87
|
-
});
|
|
87
|
+
const redirect = parseURL(data.redirect).pathname;
|
|
88
|
+
data = await this.loadRouteData(redirect);
|
|
89
|
+
data.canonical = redirect;
|
|
88
90
|
}
|
|
91
|
+
return data;
|
|
92
|
+
})
|
|
93
|
+
.then((data) => {
|
|
89
94
|
this.entries.set(cacheKey, new Promise((resolve) => resolve(data)));
|
|
90
95
|
return data;
|
|
91
96
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { parse as qsParse, stringify as qsStringify } from "qs";
|
|
2
|
-
import { parseURL, resolveURL, stringifyParsedURL, withoutTrailingSlash } from "ufo";
|
|
2
|
+
import { parseURL, resolveURL, stringifyParsedURL, withoutTrailingSlash, withTrailingSlash } from "ufo";
|
|
3
3
|
export function isSameOrigin(url) {
|
|
4
4
|
if (typeof document === "undefined") {
|
|
5
5
|
return url.startsWith("/");
|
|
@@ -81,6 +81,7 @@ export function normalizeRoute(route) {
|
|
|
81
81
|
export function stringifyRouteLink(route) {
|
|
82
82
|
return stringifyParsedURL({
|
|
83
83
|
...route,
|
|
84
|
+
pathname: withTrailingSlash(route.pathname),
|
|
84
85
|
search: stringifyQuery(route.query),
|
|
85
86
|
});
|
|
86
87
|
}
|
|
@@ -2,11 +2,24 @@
|
|
|
2
2
|
import { splitSetCookieString } from "cookie-es";
|
|
3
3
|
import { getProxyRequestHeaders, getRequestURL, getWebRequest } from "vinxi/http";
|
|
4
4
|
import { ServerContext } from "./server-context.js";
|
|
5
|
+
import { renderErrorPage } from "./render-ssr-page.js";
|
|
5
6
|
export async function proxyWpAdmin(event) {
|
|
6
7
|
const serverContext = ServerContext.main;
|
|
7
|
-
const replaceUrls = serverContext.replaceUrls;
|
|
8
8
|
const req = getWebRequest(event);
|
|
9
|
-
const
|
|
9
|
+
const reqUrl = getRequestURL(event);
|
|
10
|
+
const serverlessConfig = serverContext.config.serverless;
|
|
11
|
+
if (!serverContext.dev) {
|
|
12
|
+
if (reqUrl.pathname.toLowerCase().match(/\/+(graphql|wp\-(admin|login|json))/)) {
|
|
13
|
+
if (serverlessConfig.admin === "hide") {
|
|
14
|
+
return renderErrorPage({
|
|
15
|
+
code: 404,
|
|
16
|
+
pathname: reqUrl.pathname,
|
|
17
|
+
title: "Not Found",
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
const proxyUrl = serverContext.getOriginUrl(reqUrl.href);
|
|
10
23
|
// Prepare request headers to be sent to the origin server
|
|
11
24
|
const proxyHeaders = getProxyRequestHeaders(event);
|
|
12
25
|
proxyHeaders["X-ED-Dev-Proxy"] = "true";
|
|
@@ -32,8 +45,8 @@ export async function proxyWpAdmin(event) {
|
|
|
32
45
|
cookies.push(...splitSetCookieString(value));
|
|
33
46
|
return;
|
|
34
47
|
}
|
|
35
|
-
if (key === "location"
|
|
36
|
-
value = replaceUrls(value);
|
|
48
|
+
if (key === "location") {
|
|
49
|
+
value = serverContext.replaceUrls(value);
|
|
37
50
|
}
|
|
38
51
|
res.headers.set(key, value);
|
|
39
52
|
});
|
|
@@ -47,9 +60,7 @@ export async function proxyWpAdmin(event) {
|
|
|
47
60
|
// Replace URLs pointing to the origin server from the response itself
|
|
48
61
|
// This is only done for text-based content types, like application/json, text/plain, text/html etc
|
|
49
62
|
if (contentType?.match(/(application|text)\//)) {
|
|
50
|
-
|
|
51
|
-
body = replaceUrls((await response.text()) ?? "");
|
|
52
|
-
}
|
|
63
|
+
body = serverContext.replaceUrls((await response.text()) ?? "", reqUrl.origin);
|
|
53
64
|
// If the content type is text/html, inject the Vite assets into the response — assuming the placeholder comments are found
|
|
54
65
|
if (contentType.startsWith("text/html")) {
|
|
55
66
|
const clientManifest = serverContext.runtime.getManifest("admin");
|
|
@@ -6,6 +6,14 @@ type SSRArgs = {
|
|
|
6
6
|
export declare function getSsrStream(args: SSRArgs): Promise<ReadableStream<Uint8Array>>;
|
|
7
7
|
type RenderArgs = {
|
|
8
8
|
pathname: string;
|
|
9
|
+
statusCode?: number;
|
|
10
|
+
newOrigin?: string;
|
|
9
11
|
};
|
|
10
12
|
export declare function renderPage(args: RenderArgs): Promise<Response>;
|
|
13
|
+
type RenderErrorPageArgs = {
|
|
14
|
+
pathname: string;
|
|
15
|
+
code: number;
|
|
16
|
+
title: string;
|
|
17
|
+
};
|
|
18
|
+
export declare function renderErrorPage(args: RenderErrorPageArgs): Promise<Response>;
|
|
11
19
|
export {};
|
|
@@ -60,6 +60,7 @@ export async function renderPage(args) {
|
|
|
60
60
|
withAppData: false,
|
|
61
61
|
headers: {},
|
|
62
62
|
query: {},
|
|
63
|
+
newOrigin: args.newOrigin,
|
|
63
64
|
}),
|
|
64
65
|
]);
|
|
65
66
|
let data;
|
|
@@ -67,6 +68,7 @@ export async function renderPage(args) {
|
|
|
67
68
|
data = await response.json();
|
|
68
69
|
data.appData = appData;
|
|
69
70
|
data.trackers = trackers;
|
|
71
|
+
responseInit.status = response.status;
|
|
70
72
|
}
|
|
71
73
|
catch (err) {
|
|
72
74
|
data = {
|
|
@@ -74,6 +76,7 @@ export async function renderPage(args) {
|
|
|
74
76
|
viewType: "react",
|
|
75
77
|
viewData: {},
|
|
76
78
|
appData: appData,
|
|
79
|
+
trackers: trackers,
|
|
77
80
|
};
|
|
78
81
|
console.error(err);
|
|
79
82
|
responseInit.status = 500;
|
|
@@ -98,3 +101,46 @@ export async function renderPage(args) {
|
|
|
98
101
|
});
|
|
99
102
|
}
|
|
100
103
|
}
|
|
104
|
+
export async function renderErrorPage(args) {
|
|
105
|
+
return renderPage({
|
|
106
|
+
pathname: "/_error",
|
|
107
|
+
statusCode: args.code,
|
|
108
|
+
});
|
|
109
|
+
// const serverContext = ServerContext.main
|
|
110
|
+
// let headers = new Headers()
|
|
111
|
+
// let responseInit: ResponseInit = {
|
|
112
|
+
// headers,
|
|
113
|
+
// }
|
|
114
|
+
// try {
|
|
115
|
+
// const { appData, trackers } = await serverContext.fetchAppData()
|
|
116
|
+
// let data: RouteDataWithTrackers
|
|
117
|
+
// data = {
|
|
118
|
+
// view: "_error",
|
|
119
|
+
// viewType: "react",
|
|
120
|
+
// viewData: {},
|
|
121
|
+
// appData,
|
|
122
|
+
// trackers,
|
|
123
|
+
// }
|
|
124
|
+
// responseInit.status = 500
|
|
125
|
+
// headers.set("Content-Type", "text/html; charset=utf-8")
|
|
126
|
+
// const stream = await getSsrStream({
|
|
127
|
+
// ...args,
|
|
128
|
+
// initialData: data,
|
|
129
|
+
// })
|
|
130
|
+
// return new Response(stream, responseInit)
|
|
131
|
+
// } catch (err) {
|
|
132
|
+
// console.error(err)
|
|
133
|
+
// return new Response(
|
|
134
|
+
// '<!DOCTYPE html><html><head><title>500 Internal Server Error</title></head><body><h1>500 Internal Server Error</h1><p>"' +
|
|
135
|
+
// String(err) +
|
|
136
|
+
// '"</p></body></html>',
|
|
137
|
+
// {
|
|
138
|
+
// status: 500,
|
|
139
|
+
// statusText: "Internal Server Error",
|
|
140
|
+
// headers: {
|
|
141
|
+
// "Content-Type": "text/html; charset=utf-8",
|
|
142
|
+
// },
|
|
143
|
+
// },
|
|
144
|
+
// )
|
|
145
|
+
// }
|
|
146
|
+
}
|
|
@@ -23,22 +23,25 @@ type ServerAppData = {
|
|
|
23
23
|
export declare class ServerContext {
|
|
24
24
|
dev: boolean;
|
|
25
25
|
origin: string;
|
|
26
|
-
|
|
26
|
+
_urlReplacer?: (text: string, origin?: string) => string;
|
|
27
27
|
rpcBases: string[];
|
|
28
28
|
config: EDConfig;
|
|
29
29
|
static main: ServerContext;
|
|
30
30
|
constructor(conf: ServerContextArgs);
|
|
31
|
+
replaceUrls(text: string, origin?: string): string;
|
|
31
32
|
get runtime(): ServerContextRuntime;
|
|
32
33
|
static setRuntime(rt: ServerContextRuntime): void;
|
|
33
34
|
getOriginUrl(url: string): string;
|
|
34
35
|
fetchOrigin(url: string, opts?: RequestInit & {
|
|
35
36
|
replaceUrls?: boolean;
|
|
37
|
+
newOrigin?: string;
|
|
36
38
|
}): Promise<Response>;
|
|
37
39
|
fetchRouteData(req: {
|
|
38
40
|
pathname: string;
|
|
39
41
|
query?: Record<string, any>;
|
|
40
42
|
headers?: RequestHeaders;
|
|
41
43
|
withAppData?: boolean;
|
|
44
|
+
newOrigin?: string;
|
|
42
45
|
}): Promise<Response>;
|
|
43
46
|
fetchAppData(): Promise<ServerAppData>;
|
|
44
47
|
extractRequestHeaders(req?: RequestHeaders): Partial<Record<import("vinxi/http").HTTPHeaderName, string | undefined>>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { parseURL, stringifyParsedURL, withQuery } from "ufo";
|
|
1
|
+
import { parseURL, stringifyParsedURL, withQuery, withTrailingSlash } from "ufo";
|
|
2
2
|
import { filterHeader } from "./utils/headers.js";
|
|
3
3
|
import { createUrlReplacer } from "./utils/replace-host.js";
|
|
4
4
|
const PROXY_RESPONSE_HEADERS = ["content-type", "set-cookie", /^x-/, "cache-control", /woocommerce/];
|
|
@@ -17,7 +17,7 @@ let runtime;
|
|
|
17
17
|
export class ServerContext {
|
|
18
18
|
dev;
|
|
19
19
|
origin;
|
|
20
|
-
|
|
20
|
+
_urlReplacer;
|
|
21
21
|
rpcBases = [];
|
|
22
22
|
config;
|
|
23
23
|
static main;
|
|
@@ -27,10 +27,16 @@ export class ServerContext {
|
|
|
27
27
|
this.rpcBases = conf.rpcBases ?? [];
|
|
28
28
|
this.config = conf.config;
|
|
29
29
|
if (conf.replaceUrls) {
|
|
30
|
-
this.
|
|
30
|
+
this._urlReplacer = createUrlReplacer(conf.replaceUrls);
|
|
31
31
|
}
|
|
32
32
|
ServerContext.main = this;
|
|
33
33
|
}
|
|
34
|
+
replaceUrls(text, origin) {
|
|
35
|
+
if (this._urlReplacer) {
|
|
36
|
+
return this._urlReplacer(text, origin);
|
|
37
|
+
}
|
|
38
|
+
return text;
|
|
39
|
+
}
|
|
34
40
|
get runtime() {
|
|
35
41
|
return runtime;
|
|
36
42
|
}
|
|
@@ -66,8 +72,8 @@ export class ServerContext {
|
|
|
66
72
|
});
|
|
67
73
|
// console.log("Returning headers", headers)
|
|
68
74
|
let text = await response.text();
|
|
69
|
-
if (opts?.replaceUrls
|
|
70
|
-
text = this.replaceUrls(text);
|
|
75
|
+
if (opts?.replaceUrls) {
|
|
76
|
+
text = this.replaceUrls(text, opts.newOrigin);
|
|
71
77
|
}
|
|
72
78
|
return new Response(text, {
|
|
73
79
|
status: response.status,
|
|
@@ -76,22 +82,40 @@ export class ServerContext {
|
|
|
76
82
|
});
|
|
77
83
|
}
|
|
78
84
|
async fetchRouteData(req) {
|
|
79
|
-
const fetchUrl = withQuery(req.pathname, {
|
|
85
|
+
const fetchUrl = withQuery(withTrailingSlash(req.pathname), {
|
|
80
86
|
...req.query,
|
|
81
87
|
_props: "1",
|
|
82
88
|
_ssr: "1",
|
|
83
89
|
_debug: this.dev ? "1" : undefined,
|
|
84
90
|
});
|
|
85
91
|
// console.log("Fetching route data", req.pathname)
|
|
86
|
-
const result = this.fetchOrigin(fetchUrl, {
|
|
92
|
+
const result = await this.fetchOrigin(fetchUrl, {
|
|
87
93
|
cache: "no-cache",
|
|
88
94
|
replaceUrls: true,
|
|
95
|
+
newOrigin: req.newOrigin,
|
|
89
96
|
headers: {
|
|
90
97
|
"Content-Type": "application/json",
|
|
91
98
|
Accept: "application/json",
|
|
92
99
|
},
|
|
100
|
+
redirect: "manual",
|
|
93
101
|
});
|
|
94
|
-
|
|
102
|
+
if (result.headers.get("content-type") && result.headers.get("location")) {
|
|
103
|
+
let location = result.headers.get("location");
|
|
104
|
+
let status = result.status;
|
|
105
|
+
if (this.replaceUrls) {
|
|
106
|
+
location = this.replaceUrls(location);
|
|
107
|
+
}
|
|
108
|
+
const headers = new Headers({
|
|
109
|
+
...result.headers,
|
|
110
|
+
});
|
|
111
|
+
headers.delete("location");
|
|
112
|
+
return new Response(JSON.stringify({
|
|
113
|
+
redirect: location,
|
|
114
|
+
status: status,
|
|
115
|
+
}), {
|
|
116
|
+
headers: headers,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
95
119
|
return result;
|
|
96
120
|
}
|
|
97
121
|
async fetchAppData() {
|
|
@@ -130,7 +154,6 @@ export class ServerContext {
|
|
|
130
154
|
"Content-Type": "application/json",
|
|
131
155
|
Accept: "application/json",
|
|
132
156
|
},
|
|
133
|
-
redirect: "manual",
|
|
134
157
|
});
|
|
135
158
|
}
|
|
136
159
|
async fetchMutation(req) {
|
|
@@ -145,7 +168,6 @@ export class ServerContext {
|
|
|
145
168
|
Accept: "application/json",
|
|
146
169
|
},
|
|
147
170
|
body: JSON.stringify(req.body),
|
|
148
|
-
redirect: "manual",
|
|
149
171
|
});
|
|
150
172
|
}
|
|
151
173
|
get allowedCorsOrigins() {
|
|
@@ -2,7 +2,7 @@ export function createUrlReplacer(conf) {
|
|
|
2
2
|
// Create a regular expression to match the URL
|
|
3
3
|
// Note that that the regex doesn't necessarily match the entire URL
|
|
4
4
|
const lookup = new RegExp(conf.from.replace(/https?[:\\\/]+/, "https?[:\\/\\\\]+") + "([a-z0-9\\-_/\\\\]+)", "ig");
|
|
5
|
-
return (text) => {
|
|
5
|
+
return (text, newOrigin) => {
|
|
6
6
|
return text.replace(lookup, (url) => {
|
|
7
7
|
// Strip out the origin, to create a relative path
|
|
8
8
|
const path = url.replace(/https?:[\/\\]+[^\/\\]+/, "");
|
|
@@ -18,10 +18,19 @@ export function createUrlReplacer(conf) {
|
|
|
18
18
|
return url;
|
|
19
19
|
}
|
|
20
20
|
else {
|
|
21
|
-
|
|
21
|
+
break;
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
|
+
console.log("Replacing", url, "with", newOrigin);
|
|
26
|
+
if (newOrigin) {
|
|
27
|
+
if (isEscaped) {
|
|
28
|
+
return newOrigin.replace(/\//g, "\\/") + path;
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
return newOrigin + path;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
25
34
|
return path;
|
|
26
35
|
// if (path.startsWith("/wp-content/uploads/")) {
|
|
27
36
|
// if (!conf.ignoreUploads) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "2.0.0-beta.
|
|
1
|
+
export declare const VERSION = "2.0.0-beta.71";
|
package/dist/node/cli/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = "2.0.0-beta.
|
|
1
|
+
export const VERSION = "2.0.0-beta.71";
|
|
@@ -33,6 +33,20 @@ export function createVinxiApp(args) {
|
|
|
33
33
|
varies: [],
|
|
34
34
|
},
|
|
35
35
|
},
|
|
36
|
+
"/robots.txt": {
|
|
37
|
+
proxy: joinURL(args.origin, "robots.txt"),
|
|
38
|
+
static: true,
|
|
39
|
+
cache: {
|
|
40
|
+
maxAge: 3600,
|
|
41
|
+
varies: [],
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
"/sitemap*.xml": {
|
|
45
|
+
cache: {
|
|
46
|
+
maxAge: 3600,
|
|
47
|
+
swr: true,
|
|
48
|
+
},
|
|
49
|
+
},
|
|
36
50
|
"/wp-content/plugins/**": {
|
|
37
51
|
proxy: joinURL(args.origin, "wp-content/plugins/**"),
|
|
38
52
|
headers: {
|
|
@@ -79,12 +93,18 @@ export function createVinxiApp(args) {
|
|
|
79
93
|
},
|
|
80
94
|
},
|
|
81
95
|
routers: [
|
|
82
|
-
{
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
96
|
+
...args.config.serverless.themeAssets.map((folder) => {
|
|
97
|
+
const folderName = folder
|
|
98
|
+
.split("/")
|
|
99
|
+
.filter((p) => !p.includes("*") && p !== ".")
|
|
100
|
+
.join("/");
|
|
101
|
+
return {
|
|
102
|
+
name: "public_" + folderName,
|
|
103
|
+
type: "static",
|
|
104
|
+
dir: "./" + folderName,
|
|
105
|
+
base: joinURL(args.publicUrl, folderName),
|
|
106
|
+
};
|
|
107
|
+
}),
|
|
88
108
|
{
|
|
89
109
|
name: "data-api",
|
|
90
110
|
type: "http",
|
|
@@ -20,7 +20,7 @@ export function createVinxiCodegen(opts) {
|
|
|
20
20
|
name: "context.ts",
|
|
21
21
|
generate: async () => {
|
|
22
22
|
const args = {
|
|
23
|
-
dev:
|
|
23
|
+
dev: opts.mode === "development",
|
|
24
24
|
origin: project.origin,
|
|
25
25
|
replaceUrls: {
|
|
26
26
|
from: project.origin,
|
|
@@ -181,7 +181,7 @@ export function createVinxiCodegen(opts) {
|
|
|
181
181
|
name: "handler.data-api.ts",
|
|
182
182
|
generate: code /* tsx */ `
|
|
183
183
|
/// <reference types="vinxi/types/server" />
|
|
184
|
-
import { createRouter, eventHandler, getRouterParam, getQuery, getWebRequest, getRequestHeaders } from "vinxi/http"
|
|
184
|
+
import { createRouter, eventHandler, getRouterParam, getQuery, getWebRequest, getRequestHeaders, getRequestURL } from "vinxi/http"
|
|
185
185
|
import { serverContext } from "./context.js"
|
|
186
186
|
|
|
187
187
|
const router = createRouter()
|
|
@@ -189,10 +189,12 @@ export function createVinxiCodegen(opts) {
|
|
|
189
189
|
"/route/",
|
|
190
190
|
eventHandler(async (event) => {
|
|
191
191
|
const id = "/"
|
|
192
|
+
const url = getRequestURL(event);
|
|
192
193
|
|
|
193
194
|
return await serverContext.fetchRouteData({
|
|
194
195
|
pathname: id,
|
|
195
196
|
withAppData: false,
|
|
197
|
+
newOrigin: url.origin,
|
|
196
198
|
})
|
|
197
199
|
}),
|
|
198
200
|
)
|
|
@@ -200,10 +202,12 @@ export function createVinxiCodegen(opts) {
|
|
|
200
202
|
"/route/**:name",
|
|
201
203
|
eventHandler(async (event) => {
|
|
202
204
|
const id = "/" + getRouterParam(event, "name")
|
|
205
|
+
const url = getRequestURL(event);
|
|
203
206
|
|
|
204
207
|
return await serverContext.fetchRouteData({
|
|
205
208
|
pathname: id,
|
|
206
209
|
withAppData: false,
|
|
210
|
+
newOrigin: url.origin,
|
|
207
211
|
})
|
|
208
212
|
}),
|
|
209
213
|
)
|
|
@@ -268,7 +272,7 @@ export function createVinxiCodegen(opts) {
|
|
|
268
272
|
return proxyWpAdmin(event)
|
|
269
273
|
}
|
|
270
274
|
|
|
271
|
-
return renderPage({ pathname: url.pathname })
|
|
275
|
+
return renderPage({ pathname: url.pathname, newOrigin: url.origin })
|
|
272
276
|
}
|
|
273
277
|
})
|
|
274
278
|
`,
|
|
@@ -28,6 +28,7 @@ export declare const EDConfigSchema: z.ZodObject<{
|
|
|
28
28
|
enabled: z.ZodDefault<z.ZodBoolean>;
|
|
29
29
|
uploads: z.ZodEnum<["proxy", "remote"]>;
|
|
30
30
|
plugins: z.ZodDefault<z.ZodEnum<["proxy", "remote"]>>;
|
|
31
|
+
admin: z.ZodDefault<z.ZodEnum<["proxy", "hide"]>>;
|
|
31
32
|
themeAssets: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>;
|
|
32
33
|
apiOnly: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
33
34
|
endpoints: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
@@ -44,6 +45,7 @@ export declare const EDConfigSchema: z.ZodObject<{
|
|
|
44
45
|
plugins: "proxy" | "remote";
|
|
45
46
|
enabled: boolean;
|
|
46
47
|
uploads: "proxy" | "remote";
|
|
48
|
+
admin: "hide" | "proxy";
|
|
47
49
|
themeAssets: string[];
|
|
48
50
|
apiOnly: boolean;
|
|
49
51
|
endpoints: Record<string, string>;
|
|
@@ -57,6 +59,7 @@ export declare const EDConfigSchema: z.ZodObject<{
|
|
|
57
59
|
endpoints: Record<string, string>;
|
|
58
60
|
plugins?: "proxy" | "remote" | undefined;
|
|
59
61
|
enabled?: boolean | undefined;
|
|
62
|
+
admin?: "hide" | "proxy" | undefined;
|
|
60
63
|
themeAssets?: string[] | undefined;
|
|
61
64
|
apiOnly?: boolean | undefined;
|
|
62
65
|
defaultRevalidate?: number | undefined;
|
|
@@ -84,6 +87,7 @@ export declare const EDConfigSchema: z.ZodObject<{
|
|
|
84
87
|
plugins: "proxy" | "remote";
|
|
85
88
|
enabled: boolean;
|
|
86
89
|
uploads: "proxy" | "remote";
|
|
90
|
+
admin: "hide" | "proxy";
|
|
87
91
|
themeAssets: string[];
|
|
88
92
|
apiOnly: boolean;
|
|
89
93
|
endpoints: Record<string, string>;
|
|
@@ -113,6 +117,7 @@ export declare const EDConfigSchema: z.ZodObject<{
|
|
|
113
117
|
endpoints: Record<string, string>;
|
|
114
118
|
plugins?: "proxy" | "remote" | undefined;
|
|
115
119
|
enabled?: boolean | undefined;
|
|
120
|
+
admin?: "hide" | "proxy" | undefined;
|
|
116
121
|
themeAssets?: string[] | undefined;
|
|
117
122
|
apiOnly?: boolean | undefined;
|
|
118
123
|
defaultRevalidate?: number | undefined;
|
|
@@ -37,12 +37,15 @@ export const EDConfigSchema = z.object({
|
|
|
37
37
|
.enum(["proxy", "remote"])
|
|
38
38
|
.default("remote")
|
|
39
39
|
.describe("Whether to proxy plugin assets or serve them from the serverless endpoint.\nDefault is `remote`, but `proxy` can be used to hide the CMS origin."),
|
|
40
|
-
|
|
40
|
+
admin: z
|
|
41
|
+
.enum(["proxy", "hide"])
|
|
42
|
+
.default("proxy")
|
|
43
|
+
.describe("How to handle the WordPress admin URLs.\nDefault is `proxy`, which will proxy the admin URLs to the CMS origin. When set to `hide`, all /wp-admin, /wp-json and /wp-login.php URLs will show a 404 page.\nHas no effect in dev mode."),
|
|
41
44
|
themeAssets: z
|
|
42
45
|
.array(z.string())
|
|
43
46
|
.optional()
|
|
44
47
|
.default(["assets"])
|
|
45
|
-
.describe('
|
|
48
|
+
.describe('Asset folders to include in a serverless deployment.\nDefault is `["assets"]`'),
|
|
46
49
|
apiOnly: z.boolean().optional().default(false).describe("Whether to deploy only the API, not the frontend"),
|
|
47
50
|
endpoints: z
|
|
48
51
|
.record(z.string(), z.string())
|