eddev 2.0.0-beta.72 → 2.0.0-beta.74
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/lib/devtools/hooks/useTailwind.d.ts +16 -16
- package/dist/app/server/proxy-wp-admin.js +1 -1
- package/dist/app/server/render-ssr-page.js +0 -3
- package/dist/app/server/server-context.d.ts +3 -5
- package/dist/app/server/server-context.js +124 -50
- package/dist/app/server/utils/replace-host.js +0 -1
- package/dist/app/server/utils/swr-cache.d.ts +4 -7
- package/dist/app/server/utils/swr-cache.js +23 -21
- package/dist/node/cli/cli-worker.js +1 -1
- package/dist/node/cli/cli.js +18 -4
- package/dist/node/cli/version.d.ts +1 -1
- package/dist/node/cli/version.js +1 -1
- package/dist/node/compiler/vinxi-codegen.js +1 -3
- package/dist/node/graphql/graphql-codegen.js +1 -1
- package/dist/node/graphql/graphql-schema-loader.d.ts +2 -1
- package/dist/node/graphql/graphql-schema-loader.js +5 -16
- package/dist/node/project/config.d.ts +19 -15
- package/dist/node/project/config.js +11 -4
- package/dist/node/project/env.d.ts +4 -0
- package/dist/node/project/env.js +1 -0
- package/dist/node/project/project.d.ts +6 -0
- package/dist/node/project/project.js +29 -0
- package/dist/node/project/wp-info.d.ts +1 -0
- package/dist/node/project/wp-info.js +6 -2
- package/dist/node/utils/fetch-wp.d.ts +1 -0
- package/dist/node/utils/fetch-wp.js +27 -0
- package/dist/node/utils/is-deploying.js +1 -1
- package/package.json +4 -2
|
@@ -368,8 +368,8 @@ export declare function useTailwindConfig(): {
|
|
|
368
368
|
readonly opacity?: ((utils: import("tailwindcss/types/config.js").PluginUtils) => import("tailwindcss/types/config.js").KeyValuePair<string, string>) | {
|
|
369
369
|
readonly [x: string]: string;
|
|
370
370
|
} | undefined;
|
|
371
|
-
readonly boxShadow?: ((utils: import("tailwindcss/types/config.js").PluginUtils) => import("tailwindcss/types/config.js").KeyValuePair<string, string>) | {
|
|
372
|
-
readonly [x: string]: string;
|
|
371
|
+
readonly boxShadow?: ((utils: import("tailwindcss/types/config.js").PluginUtils) => import("tailwindcss/types/config.js").KeyValuePair<string, string | string[]>) | {
|
|
372
|
+
readonly [x: string]: string | readonly string[];
|
|
373
373
|
} | undefined;
|
|
374
374
|
readonly boxShadowColor?: ((utils: import("tailwindcss/types/config.js").PluginUtils) => import("tailwindcss/types/config.js").RecursiveKeyValuePair<string, string>) | {
|
|
375
375
|
readonly [x: string]: string | any;
|
|
@@ -776,8 +776,8 @@ export declare function useTailwindConfig(): {
|
|
|
776
776
|
readonly opacity?: ((utils: import("tailwindcss/types/config.js").PluginUtils) => import("tailwindcss/types/config.js").KeyValuePair<string, string>) | {
|
|
777
777
|
readonly [x: string]: string;
|
|
778
778
|
} | undefined;
|
|
779
|
-
readonly boxShadow?: ((utils: import("tailwindcss/types/config.js").PluginUtils) => import("tailwindcss/types/config.js").KeyValuePair<string, string>) | {
|
|
780
|
-
readonly [x: string]: string;
|
|
779
|
+
readonly boxShadow?: ((utils: import("tailwindcss/types/config.js").PluginUtils) => import("tailwindcss/types/config.js").KeyValuePair<string, string | string[]>) | {
|
|
780
|
+
readonly [x: string]: string | readonly string[];
|
|
781
781
|
} | undefined;
|
|
782
782
|
readonly boxShadowColor?: ((utils: import("tailwindcss/types/config.js").PluginUtils) => import("tailwindcss/types/config.js").RecursiveKeyValuePair<string, string>) | {
|
|
783
783
|
readonly [x: string]: string | any;
|
|
@@ -1413,8 +1413,8 @@ export declare function useTailwindConfig(): {
|
|
|
1413
1413
|
readonly opacity?: ((utils: import("tailwindcss/types/config.js").PluginUtils) => import("tailwindcss/types/config.js").KeyValuePair<string, string>) | {
|
|
1414
1414
|
readonly [x: string]: string;
|
|
1415
1415
|
} | undefined;
|
|
1416
|
-
readonly boxShadow?: ((utils: import("tailwindcss/types/config.js").PluginUtils) => import("tailwindcss/types/config.js").KeyValuePair<string, string>) | {
|
|
1417
|
-
readonly [x: string]: string;
|
|
1416
|
+
readonly boxShadow?: ((utils: import("tailwindcss/types/config.js").PluginUtils) => import("tailwindcss/types/config.js").KeyValuePair<string, string | string[]>) | {
|
|
1417
|
+
readonly [x: string]: string | readonly string[];
|
|
1418
1418
|
} | undefined;
|
|
1419
1419
|
readonly boxShadowColor?: ((utils: import("tailwindcss/types/config.js").PluginUtils) => import("tailwindcss/types/config.js").RecursiveKeyValuePair<string, string>) | {
|
|
1420
1420
|
readonly [x: string]: string | any;
|
|
@@ -1821,8 +1821,8 @@ export declare function useTailwindConfig(): {
|
|
|
1821
1821
|
readonly opacity?: ((utils: import("tailwindcss/types/config.js").PluginUtils) => import("tailwindcss/types/config.js").KeyValuePair<string, string>) | {
|
|
1822
1822
|
readonly [x: string]: string;
|
|
1823
1823
|
} | undefined;
|
|
1824
|
-
readonly boxShadow?: ((utils: import("tailwindcss/types/config.js").PluginUtils) => import("tailwindcss/types/config.js").KeyValuePair<string, string>) | {
|
|
1825
|
-
readonly [x: string]: string;
|
|
1824
|
+
readonly boxShadow?: ((utils: import("tailwindcss/types/config.js").PluginUtils) => import("tailwindcss/types/config.js").KeyValuePair<string, string | string[]>) | {
|
|
1825
|
+
readonly [x: string]: string | readonly string[];
|
|
1826
1826
|
} | undefined;
|
|
1827
1827
|
readonly boxShadowColor?: ((utils: import("tailwindcss/types/config.js").PluginUtils) => import("tailwindcss/types/config.js").RecursiveKeyValuePair<string, string>) | {
|
|
1828
1828
|
readonly [x: string]: string | any;
|
|
@@ -2433,8 +2433,8 @@ export declare function useTailwindConfig(): {
|
|
|
2433
2433
|
readonly opacity?: ((utils: import("tailwindcss/types/config.js").PluginUtils) => import("tailwindcss/types/config.js").KeyValuePair<string, string>) | {
|
|
2434
2434
|
readonly [x: string]: string;
|
|
2435
2435
|
} | undefined;
|
|
2436
|
-
readonly boxShadow?: ((utils: import("tailwindcss/types/config.js").PluginUtils) => import("tailwindcss/types/config.js").KeyValuePair<string, string>) | {
|
|
2437
|
-
readonly [x: string]: string;
|
|
2436
|
+
readonly boxShadow?: ((utils: import("tailwindcss/types/config.js").PluginUtils) => import("tailwindcss/types/config.js").KeyValuePair<string, string | string[]>) | {
|
|
2437
|
+
readonly [x: string]: string | readonly string[];
|
|
2438
2438
|
} | undefined;
|
|
2439
2439
|
readonly boxShadowColor?: ((utils: import("tailwindcss/types/config.js").PluginUtils) => import("tailwindcss/types/config.js").RecursiveKeyValuePair<string, string>) | {
|
|
2440
2440
|
readonly [x: string]: string | any;
|
|
@@ -2841,8 +2841,8 @@ export declare function useTailwindConfig(): {
|
|
|
2841
2841
|
readonly opacity?: ((utils: import("tailwindcss/types/config.js").PluginUtils) => import("tailwindcss/types/config.js").KeyValuePair<string, string>) | {
|
|
2842
2842
|
readonly [x: string]: string;
|
|
2843
2843
|
} | undefined;
|
|
2844
|
-
readonly boxShadow?: ((utils: import("tailwindcss/types/config.js").PluginUtils) => import("tailwindcss/types/config.js").KeyValuePair<string, string>) | {
|
|
2845
|
-
readonly [x: string]: string;
|
|
2844
|
+
readonly boxShadow?: ((utils: import("tailwindcss/types/config.js").PluginUtils) => import("tailwindcss/types/config.js").KeyValuePair<string, string | string[]>) | {
|
|
2845
|
+
readonly [x: string]: string | readonly string[];
|
|
2846
2846
|
} | undefined;
|
|
2847
2847
|
readonly boxShadowColor?: ((utils: import("tailwindcss/types/config.js").PluginUtils) => import("tailwindcss/types/config.js").RecursiveKeyValuePair<string, string>) | {
|
|
2848
2848
|
readonly [x: string]: string | any;
|
|
@@ -3478,8 +3478,8 @@ export declare function useTailwindConfig(): {
|
|
|
3478
3478
|
readonly opacity?: ((utils: import("tailwindcss/types/config.js").PluginUtils) => import("tailwindcss/types/config.js").KeyValuePair<string, string>) | {
|
|
3479
3479
|
readonly [x: string]: string;
|
|
3480
3480
|
} | undefined;
|
|
3481
|
-
readonly boxShadow?: ((utils: import("tailwindcss/types/config.js").PluginUtils) => import("tailwindcss/types/config.js").KeyValuePair<string, string>) | {
|
|
3482
|
-
readonly [x: string]: string;
|
|
3481
|
+
readonly boxShadow?: ((utils: import("tailwindcss/types/config.js").PluginUtils) => import("tailwindcss/types/config.js").KeyValuePair<string, string | string[]>) | {
|
|
3482
|
+
readonly [x: string]: string | readonly string[];
|
|
3483
3483
|
} | undefined;
|
|
3484
3484
|
readonly boxShadowColor?: ((utils: import("tailwindcss/types/config.js").PluginUtils) => import("tailwindcss/types/config.js").RecursiveKeyValuePair<string, string>) | {
|
|
3485
3485
|
readonly [x: string]: string | any;
|
|
@@ -3886,8 +3886,8 @@ export declare function useTailwindConfig(): {
|
|
|
3886
3886
|
readonly opacity?: ((utils: import("tailwindcss/types/config.js").PluginUtils) => import("tailwindcss/types/config.js").KeyValuePair<string, string>) | {
|
|
3887
3887
|
readonly [x: string]: string;
|
|
3888
3888
|
} | undefined;
|
|
3889
|
-
readonly boxShadow?: ((utils: import("tailwindcss/types/config.js").PluginUtils) => import("tailwindcss/types/config.js").KeyValuePair<string, string>) | {
|
|
3890
|
-
readonly [x: string]: string;
|
|
3889
|
+
readonly boxShadow?: ((utils: import("tailwindcss/types/config.js").PluginUtils) => import("tailwindcss/types/config.js").KeyValuePair<string, string | string[]>) | {
|
|
3890
|
+
readonly [x: string]: string | readonly string[];
|
|
3891
3891
|
} | undefined;
|
|
3892
3892
|
readonly boxShadowColor?: ((utils: import("tailwindcss/types/config.js").PluginUtils) => import("tailwindcss/types/config.js").RecursiveKeyValuePair<string, string>) | {
|
|
3893
3893
|
readonly [x: string]: string | any;
|
|
@@ -9,7 +9,7 @@ export async function proxyWpAdmin(event) {
|
|
|
9
9
|
const reqUrl = getRequestURL(event);
|
|
10
10
|
const serverlessConfig = serverContext.config.serverless;
|
|
11
11
|
if (!serverContext.dev) {
|
|
12
|
-
if (reqUrl.pathname.toLowerCase().match(/\/+(graphql|wp\-(admin|login|json))/)) {
|
|
12
|
+
if (reqUrl.pathname.toLowerCase().match(/\/+(graphql|xmlrpc|index\.php|wp\-(admin|login|json))/)) {
|
|
13
13
|
if (serverlessConfig.admin === "hide") {
|
|
14
14
|
return renderErrorPage({
|
|
15
15
|
code: 404,
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { RequestHeaders } from "vinxi/http";
|
|
2
|
-
import { UrlReplacerConf } from "./utils/replace-host.js";
|
|
3
1
|
import { Manifest } from "vinxi/dist/types/types/manifest";
|
|
4
|
-
import {
|
|
2
|
+
import { RequestHeaders } from "vinxi/http";
|
|
5
3
|
import type { EDConfig } from "../../node/project/config.js";
|
|
4
|
+
import { TrackerTags } from "../lib/routing/types.js";
|
|
5
|
+
import { UrlReplacerConf } from "./utils/replace-host.js";
|
|
6
6
|
export type ServerContextArgs = {
|
|
7
7
|
dev: boolean;
|
|
8
8
|
origin: string;
|
|
@@ -38,9 +38,7 @@ export declare class ServerContext {
|
|
|
38
38
|
}): Promise<Response>;
|
|
39
39
|
fetchRouteData(req: {
|
|
40
40
|
pathname: string;
|
|
41
|
-
query?: Record<string, any>;
|
|
42
41
|
headers?: RequestHeaders;
|
|
43
|
-
withAppData?: boolean;
|
|
44
42
|
newOrigin?: string;
|
|
45
43
|
}): Promise<Response>;
|
|
46
44
|
fetchAppData(): Promise<ServerAppData>;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { parseURL, stringifyParsedURL, withQuery, withTrailingSlash } from "ufo";
|
|
2
|
+
import { fetchWP } from "../../node/utils/fetch-wp.js";
|
|
2
3
|
import { filterHeader } from "./utils/headers.js";
|
|
3
4
|
import { createUrlReplacer } from "./utils/replace-host.js";
|
|
5
|
+
import { pageCache, queryCache, swr } from "./utils/swr-cache.js";
|
|
4
6
|
const PROXY_RESPONSE_HEADERS = ["content-type", "set-cookie", /^x-/, "cache-control", /woocommerce/];
|
|
5
7
|
const PROXY_REQUEST_HEADERS = [
|
|
6
8
|
"content-type",
|
|
@@ -13,6 +15,7 @@ const PROXY_REQUEST_HEADERS = [
|
|
|
13
15
|
"authorization",
|
|
14
16
|
"woocommerce-session",
|
|
15
17
|
];
|
|
18
|
+
const VARIES_HEADERS = ["Authorization", "woocommerce-session"];
|
|
16
19
|
let runtime;
|
|
17
20
|
export class ServerContext {
|
|
18
21
|
dev;
|
|
@@ -52,7 +55,7 @@ export class ServerContext {
|
|
|
52
55
|
}
|
|
53
56
|
async fetchOrigin(url, opts) {
|
|
54
57
|
url = this.getOriginUrl(url);
|
|
55
|
-
const response = await
|
|
58
|
+
const response = await fetchWP(url, {
|
|
56
59
|
...opts,
|
|
57
60
|
headers: {
|
|
58
61
|
"Content-Type": "application/json",
|
|
@@ -82,53 +85,90 @@ export class ServerContext {
|
|
|
82
85
|
});
|
|
83
86
|
}
|
|
84
87
|
async fetchRouteData(req) {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
cache:
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
88
|
+
/**
|
|
89
|
+
* Calculcate the cache key.
|
|
90
|
+
* For route data, the cache key is the pathname.
|
|
91
|
+
* TODO: Potential support for Vercel draft mode.
|
|
92
|
+
*/
|
|
93
|
+
let cacheKey = "fetchRouteData:" + req.pathname;
|
|
94
|
+
const result = await swr({
|
|
95
|
+
key: cacheKey,
|
|
96
|
+
cache: pageCache,
|
|
97
|
+
getFreshValue: async (ctx) => {
|
|
98
|
+
ctx.metadata.createdTime;
|
|
99
|
+
const fetchUrl = withQuery(withTrailingSlash(req.pathname), {
|
|
100
|
+
_props: "1",
|
|
101
|
+
_ssr: "1",
|
|
102
|
+
_debug: this.dev ? "1" : undefined,
|
|
103
|
+
});
|
|
104
|
+
const result = await this.fetchOrigin(fetchUrl, {
|
|
105
|
+
cache: "no-cache",
|
|
106
|
+
replaceUrls: true,
|
|
107
|
+
newOrigin: req.newOrigin,
|
|
108
|
+
headers: {
|
|
109
|
+
"Content-Type": "application/json",
|
|
110
|
+
Accept: "application/json",
|
|
111
|
+
},
|
|
112
|
+
redirect: "manual",
|
|
113
|
+
});
|
|
114
|
+
const preferredCacheDuration = parseInt(result.headers.get("x-ed-cache-duration") ?? "");
|
|
115
|
+
if (isFinite(preferredCacheDuration)) {
|
|
116
|
+
ctx.metadata.ttl = preferredCacheDuration * 1000;
|
|
117
|
+
}
|
|
118
|
+
let resultStatus = result.status;
|
|
119
|
+
let resultHeaders = result.headers;
|
|
120
|
+
let resultData = await result.json();
|
|
121
|
+
// Special case for redirects
|
|
122
|
+
if (result.headers.get("location")) {
|
|
123
|
+
let location = result.headers.get("location");
|
|
124
|
+
let status = result.status;
|
|
125
|
+
if (this.replaceUrls) {
|
|
126
|
+
location = this.replaceUrls(location);
|
|
127
|
+
}
|
|
128
|
+
resultHeaders.delete("location");
|
|
129
|
+
resultData = {
|
|
130
|
+
redirect: location,
|
|
131
|
+
status: status,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
if (resultData && typeof resultData === "object") {
|
|
135
|
+
resultData.__generated = new Date().toISOString();
|
|
136
|
+
}
|
|
137
|
+
return {
|
|
138
|
+
status: resultStatus,
|
|
139
|
+
headers: resultHeaders,
|
|
140
|
+
data: JSON.stringify(resultData),
|
|
141
|
+
};
|
|
99
142
|
},
|
|
100
|
-
redirect: "manual",
|
|
101
143
|
});
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
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
|
-
}
|
|
119
|
-
return result;
|
|
144
|
+
return new Response(result.data, {
|
|
145
|
+
status: result.status,
|
|
146
|
+
headers: result.headers,
|
|
147
|
+
});
|
|
120
148
|
}
|
|
121
149
|
async fetchAppData() {
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
150
|
+
const data = await swr({
|
|
151
|
+
key: "fetchAppData",
|
|
152
|
+
cache: pageCache,
|
|
153
|
+
getFreshValue: async (ctx) => {
|
|
154
|
+
const response = await this.fetchOrigin("/_appdata", {
|
|
155
|
+
cache: "no-cache",
|
|
156
|
+
replaceUrls: true,
|
|
157
|
+
headers: {
|
|
158
|
+
"Content-Type": "application/json",
|
|
159
|
+
Accept: "application/json",
|
|
160
|
+
},
|
|
161
|
+
});
|
|
162
|
+
const result = await response.json();
|
|
163
|
+
const preferredCacheDuration = parseInt(response.headers.get("x-ed-cache-duration") ?? "");
|
|
164
|
+
if (isFinite(preferredCacheDuration)) {
|
|
165
|
+
ctx.metadata.ttl = preferredCacheDuration * 1000;
|
|
166
|
+
}
|
|
167
|
+
result.__generated = new Date().toISOString();
|
|
168
|
+
return result;
|
|
128
169
|
},
|
|
129
170
|
});
|
|
130
|
-
|
|
131
|
-
return result;
|
|
171
|
+
return data;
|
|
132
172
|
}
|
|
133
173
|
extractRequestHeaders(req) {
|
|
134
174
|
const headers = {};
|
|
@@ -143,14 +183,48 @@ export class ServerContext {
|
|
|
143
183
|
}
|
|
144
184
|
async fetchNamedQuery(req) {
|
|
145
185
|
const url = `/wp-json/ed/v1/query/${req.name}?params=${encodeURIComponent(JSON.stringify(req.params))}`;
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
186
|
+
const key = `fetchNamedQuery:${req.name}:${JSON.stringify(req.params)}`;
|
|
187
|
+
const fetch = async () => {
|
|
188
|
+
const result = await this.fetchOrigin(url, {
|
|
189
|
+
cache: "no-cache",
|
|
190
|
+
replaceUrls: true,
|
|
191
|
+
headers: {
|
|
192
|
+
...this.extractRequestHeaders(req.headers),
|
|
193
|
+
"Content-Type": "application/json",
|
|
194
|
+
Accept: "application/json",
|
|
195
|
+
},
|
|
196
|
+
});
|
|
197
|
+
const preferredCacheDuration = parseInt(result.headers.get("x-ed-cache-duration") ?? "");
|
|
198
|
+
let resultStatus = result.status;
|
|
199
|
+
let resultHeaders = result.headers;
|
|
200
|
+
let resultData = await result.json();
|
|
201
|
+
if (resultData && typeof resultData === "object") {
|
|
202
|
+
resultData.__generated = new Date().toISOString();
|
|
203
|
+
}
|
|
204
|
+
return {
|
|
205
|
+
status: resultStatus,
|
|
206
|
+
headers: resultHeaders,
|
|
207
|
+
data: JSON.stringify(resultData),
|
|
208
|
+
cacheTime: isFinite(preferredCacheDuration) ? preferredCacheDuration * 1000 : undefined,
|
|
209
|
+
};
|
|
210
|
+
};
|
|
211
|
+
// If headers like 'Authorization' are set, then we shouldn't cache.
|
|
212
|
+
const hasVariedHeaders = VARIES_HEADERS.some((key) => !!req.headers[key]);
|
|
213
|
+
// Get the result, either from cache or by fetching.
|
|
214
|
+
const result = hasVariedHeaders
|
|
215
|
+
? await fetch()
|
|
216
|
+
: await swr({
|
|
217
|
+
key,
|
|
218
|
+
cache: queryCache,
|
|
219
|
+
getFreshValue: async (ctx) => {
|
|
220
|
+
const result = await fetch();
|
|
221
|
+
ctx.metadata.ttl = result.cacheTime;
|
|
222
|
+
return result;
|
|
223
|
+
},
|
|
224
|
+
});
|
|
225
|
+
return new Response(result.data, {
|
|
226
|
+
status: result.status,
|
|
227
|
+
headers: result.headers,
|
|
154
228
|
});
|
|
155
229
|
}
|
|
156
230
|
async fetchMutation(req) {
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import { Cache } from "@epic-web/cachified";
|
|
2
|
-
export declare
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
ttl?: number;
|
|
6
|
-
cache?: Cache;
|
|
7
|
-
}): Promise<T>;
|
|
1
|
+
import { Cache, CachifiedOptions } from "@epic-web/cachified";
|
|
2
|
+
export declare const pageCache: Cache<any>;
|
|
3
|
+
export declare const queryCache: Cache<any>;
|
|
4
|
+
export declare function swr<T>(args: CachifiedOptions<T>): Promise<T>;
|
|
@@ -1,29 +1,31 @@
|
|
|
1
1
|
import { LRUCache } from "lru-cache";
|
|
2
2
|
import { cachified, totalTtl } from "@epic-web/cachified";
|
|
3
|
-
|
|
4
|
-
const lruInstance = new LRUCache({ max: 1000 });
|
|
5
|
-
const lru = {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
};
|
|
3
|
+
function createCache() {
|
|
4
|
+
const lruInstance = new LRUCache({ max: 1000 });
|
|
5
|
+
const lru = {
|
|
6
|
+
set(key, value) {
|
|
7
|
+
const ttl = totalTtl(value?.metadata);
|
|
8
|
+
return lruInstance.set(key, value, {
|
|
9
|
+
ttl: ttl === Infinity ? undefined : ttl,
|
|
10
|
+
start: value?.metadata?.createdTime,
|
|
11
|
+
});
|
|
12
|
+
},
|
|
13
|
+
get(key) {
|
|
14
|
+
return lruInstance.get(key);
|
|
15
|
+
},
|
|
16
|
+
delete(key) {
|
|
17
|
+
return lruInstance.delete(key);
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
return lru;
|
|
21
|
+
}
|
|
22
|
+
export const pageCache = createCache();
|
|
23
|
+
export const queryCache = createCache();
|
|
20
24
|
export function swr(args) {
|
|
21
25
|
return cachified({
|
|
22
|
-
|
|
23
|
-
cache: args.cache ?? lru,
|
|
24
|
-
getFreshValue: args.fetcher,
|
|
25
|
-
ttl: args.ttl,
|
|
26
|
+
ttl: args.ttl ?? 10_000,
|
|
26
27
|
swr: 3600_000,
|
|
27
28
|
fallbackToCache: 15_000,
|
|
29
|
+
...args,
|
|
28
30
|
});
|
|
29
31
|
}
|
|
@@ -47,7 +47,7 @@ export class CLIWorker {
|
|
|
47
47
|
if (!isMainThread) {
|
|
48
48
|
const mode = workerData.mode;
|
|
49
49
|
/** Ignore self-signed certificate errors in dev mode */
|
|
50
|
-
process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = "0"
|
|
50
|
+
// process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = "0"
|
|
51
51
|
configureCliMode({
|
|
52
52
|
interactive: true,
|
|
53
53
|
readonly: false,
|
package/dist/node/cli/cli.js
CHANGED
|
@@ -42,7 +42,7 @@ program
|
|
|
42
42
|
// }
|
|
43
43
|
process.env["NODE_ENV"] = "development";
|
|
44
44
|
/** Ignore self-signed certificate errors in dev mode */
|
|
45
|
-
process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = "0"
|
|
45
|
+
// process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = "0"
|
|
46
46
|
serverlessLog.info(chalk.yellowBright(`⚡️ ED. Stack v${VERSION}`));
|
|
47
47
|
if (options.fast) {
|
|
48
48
|
options.mode = "graphql,serverless";
|
|
@@ -79,6 +79,12 @@ program
|
|
|
79
79
|
rootDir: process.cwd(),
|
|
80
80
|
reportPluginCompatibility: true,
|
|
81
81
|
});
|
|
82
|
+
const result = await project.verifyOriginAccess();
|
|
83
|
+
if (!result.success) {
|
|
84
|
+
projectLog.fail(result.message);
|
|
85
|
+
process.exit(1);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
82
88
|
const infoWriter = new BuildInfoWriter(project);
|
|
83
89
|
infoWriter.watch();
|
|
84
90
|
infoWriter.write();
|
|
@@ -152,7 +158,7 @@ program
|
|
|
152
158
|
.action(async (options) => {
|
|
153
159
|
process.env["NODE_ENV"] = "production";
|
|
154
160
|
/** Ignore self-signed certificate errors in dev mode */
|
|
155
|
-
process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = "0"
|
|
161
|
+
// process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = "0"
|
|
156
162
|
init(options.verbose);
|
|
157
163
|
configureCliMode({
|
|
158
164
|
interactive: false,
|
|
@@ -170,12 +176,20 @@ program
|
|
|
170
176
|
});
|
|
171
177
|
const buildServerless = options.serverless || process.env.VERCEL;
|
|
172
178
|
if (buildServerless) {
|
|
179
|
+
// Verify that the we have access to the origin
|
|
180
|
+
const result = await project.verifyOriginAccess();
|
|
181
|
+
if (!result.success) {
|
|
182
|
+
console.error(result.message);
|
|
183
|
+
process.exit(1);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
173
186
|
await buildVinxi({
|
|
174
187
|
project,
|
|
175
188
|
console,
|
|
176
189
|
});
|
|
177
190
|
}
|
|
178
191
|
else {
|
|
192
|
+
const infoWriter = new BuildInfoWriter(project);
|
|
179
193
|
// Generate bootstrap files
|
|
180
194
|
const codegen = createVinxiCodegen({
|
|
181
195
|
mode: "production",
|
|
@@ -194,7 +208,7 @@ program
|
|
|
194
208
|
const graphql = new GraphQLGenerator(project, {
|
|
195
209
|
optimize: true,
|
|
196
210
|
});
|
|
197
|
-
await Promise.all([admin.start(), frontend.start(), graphql.start()]);
|
|
211
|
+
await Promise.all([infoWriter.write(), admin.start(), frontend.start(), graphql.start()]);
|
|
198
212
|
console.log("Done building SPA WordPress");
|
|
199
213
|
}
|
|
200
214
|
});
|
|
@@ -204,7 +218,7 @@ program
|
|
|
204
218
|
.option("--host", "Hostname to serve the application", "127.0.0.1")
|
|
205
219
|
.option("--port", "Port to serve the application", "3000")
|
|
206
220
|
.action(async (options) => {
|
|
207
|
-
process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = "0"
|
|
221
|
+
// process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = "0"
|
|
208
222
|
process.env["NODE_ENV"] = "production";
|
|
209
223
|
process.env["HOST"] = options.host;
|
|
210
224
|
process.env["PORT"] = options.port;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "2.0.0-beta.
|
|
1
|
+
export declare const VERSION = "2.0.0-beta.74";
|
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.74";
|
|
@@ -193,7 +193,6 @@ export function createVinxiCodegen(opts) {
|
|
|
193
193
|
|
|
194
194
|
return await serverContext.fetchRouteData({
|
|
195
195
|
pathname: id,
|
|
196
|
-
withAppData: false,
|
|
197
196
|
newOrigin: url.origin,
|
|
198
197
|
})
|
|
199
198
|
}),
|
|
@@ -206,7 +205,6 @@ export function createVinxiCodegen(opts) {
|
|
|
206
205
|
|
|
207
206
|
return await serverContext.fetchRouteData({
|
|
208
207
|
pathname: id,
|
|
209
|
-
withAppData: false,
|
|
210
208
|
newOrigin: url.origin,
|
|
211
209
|
})
|
|
212
210
|
}),
|
|
@@ -268,7 +266,7 @@ export function createVinxiCodegen(opts) {
|
|
|
268
266
|
return handleRPC(event)
|
|
269
267
|
}
|
|
270
268
|
|
|
271
|
-
if (url.pathname.includes(".")) {
|
|
269
|
+
if (url.pathname.includes(".") || url.pathname.startsWith("/graphql")) {
|
|
272
270
|
return proxyWpAdmin(event)
|
|
273
271
|
}
|
|
274
272
|
|
|
@@ -65,7 +65,7 @@ export class GraphQLGenerator {
|
|
|
65
65
|
constructor(project, opts) {
|
|
66
66
|
this.project = project;
|
|
67
67
|
this.opts = opts;
|
|
68
|
-
this.schemaLoader = new GraphQLSchemaLoader(ProjectEnvUtils.getSafe("DEBUG_GRAPHQL_URL"));
|
|
68
|
+
this.schemaLoader = new GraphQLSchemaLoader(ProjectEnvUtils.getSafe("DEBUG_GRAPHQL_URL"), ProjectEnvUtils.getSafe("SITE_API_KEY"));
|
|
69
69
|
this.fileLoader = createGraphQLFileLoader(this.project, [
|
|
70
70
|
{
|
|
71
71
|
baseFolder: "queries/fragments",
|
|
@@ -6,8 +6,9 @@ type LoadResult = {
|
|
|
6
6
|
};
|
|
7
7
|
export declare class GraphQLSchemaLoader {
|
|
8
8
|
url: string;
|
|
9
|
+
apiKey?: string | undefined;
|
|
9
10
|
lastHash: string;
|
|
10
|
-
constructor(url: string);
|
|
11
|
+
constructor(url: string, apiKey?: string | undefined);
|
|
11
12
|
private cachedResult;
|
|
12
13
|
get(forceReload?: boolean): Promise<Error | LoadResult>;
|
|
13
14
|
load(): Promise<Error | LoadResult>;
|
|
@@ -4,11 +4,14 @@ import { introspectionFromSchema } from "graphql";
|
|
|
4
4
|
import { graphqlLog as console } from "./graphql-codegen.js";
|
|
5
5
|
import chalk from "chalk";
|
|
6
6
|
import { hash } from "object-code";
|
|
7
|
+
import { fetchWP } from "../utils/fetch-wp.js";
|
|
7
8
|
export class GraphQLSchemaLoader {
|
|
8
9
|
url;
|
|
10
|
+
apiKey;
|
|
9
11
|
lastHash = "";
|
|
10
|
-
constructor(url) {
|
|
12
|
+
constructor(url, apiKey) {
|
|
11
13
|
this.url = url;
|
|
14
|
+
this.apiKey = apiKey;
|
|
12
15
|
}
|
|
13
16
|
cachedResult = null;
|
|
14
17
|
async get(forceReload = false) {
|
|
@@ -21,21 +24,7 @@ export class GraphQLSchemaLoader {
|
|
|
21
24
|
console.info(`${this.lastHash ? "Reloading" : "Loading"} GraphQL schema from ${chalk.yellowBright(this.url)}`);
|
|
22
25
|
const rawSchema = await loadSchema(this.url, {
|
|
23
26
|
loaders: [new UrlLoader()],
|
|
24
|
-
|
|
25
|
-
// const httpsAgent = new Agent({
|
|
26
|
-
// rejectUnauthorized: false,
|
|
27
|
-
// })
|
|
28
|
-
// return fetch(url, {
|
|
29
|
-
// ...opts,
|
|
30
|
-
// agent: function (_parsedURL) {
|
|
31
|
-
// if (_parsedURL.protocol == "http:") {
|
|
32
|
-
// return undefined
|
|
33
|
-
// } else {
|
|
34
|
-
// return httpsAgent
|
|
35
|
-
// }
|
|
36
|
-
// },
|
|
37
|
-
// })
|
|
38
|
-
// },
|
|
27
|
+
fetch: fetchWP,
|
|
39
28
|
}).catch((e) => {
|
|
40
29
|
return e;
|
|
41
30
|
});
|
|
@@ -29,11 +29,15 @@ export declare const EDConfigSchema: z.ZodObject<{
|
|
|
29
29
|
uploads: z.ZodEnum<["proxy", "remote"]>;
|
|
30
30
|
plugins: z.ZodDefault<z.ZodEnum<["proxy", "remote"]>>;
|
|
31
31
|
admin: z.ZodDefault<z.ZodEnum<["proxy", "hide"]>>;
|
|
32
|
+
originProtection: z.ZodDefault<z.ZodObject<{
|
|
33
|
+
requireLogin: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
34
|
+
}, "strip", z.ZodTypeAny, {
|
|
35
|
+
requireLogin: boolean;
|
|
36
|
+
}, {
|
|
37
|
+
requireLogin?: boolean | undefined;
|
|
38
|
+
}>>;
|
|
32
39
|
themeAssets: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>;
|
|
33
|
-
apiOnly: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
34
40
|
endpoints: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
35
|
-
defaultRevalidate: z.ZodOptional<z.ZodNumber>;
|
|
36
|
-
defaultRevalidateQueries: z.ZodOptional<z.ZodNumber>;
|
|
37
41
|
cors: z.ZodOptional<z.ZodObject<{
|
|
38
42
|
origins: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
39
43
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -46,11 +50,11 @@ export declare const EDConfigSchema: z.ZodObject<{
|
|
|
46
50
|
enabled: boolean;
|
|
47
51
|
uploads: "proxy" | "remote";
|
|
48
52
|
admin: "hide" | "proxy";
|
|
53
|
+
originProtection: {
|
|
54
|
+
requireLogin: boolean;
|
|
55
|
+
};
|
|
49
56
|
themeAssets: string[];
|
|
50
|
-
apiOnly: boolean;
|
|
51
57
|
endpoints: Record<string, string>;
|
|
52
|
-
defaultRevalidate?: number | undefined;
|
|
53
|
-
defaultRevalidateQueries?: number | undefined;
|
|
54
58
|
cors?: {
|
|
55
59
|
origins?: string[] | undefined;
|
|
56
60
|
} | undefined;
|
|
@@ -60,10 +64,10 @@ export declare const EDConfigSchema: z.ZodObject<{
|
|
|
60
64
|
plugins?: "proxy" | "remote" | undefined;
|
|
61
65
|
enabled?: boolean | undefined;
|
|
62
66
|
admin?: "hide" | "proxy" | undefined;
|
|
67
|
+
originProtection?: {
|
|
68
|
+
requireLogin?: boolean | undefined;
|
|
69
|
+
} | undefined;
|
|
63
70
|
themeAssets?: string[] | undefined;
|
|
64
|
-
apiOnly?: boolean | undefined;
|
|
65
|
-
defaultRevalidate?: number | undefined;
|
|
66
|
-
defaultRevalidateQueries?: number | undefined;
|
|
67
71
|
cors?: {
|
|
68
72
|
origins?: string[] | undefined;
|
|
69
73
|
} | undefined;
|
|
@@ -88,11 +92,11 @@ export declare const EDConfigSchema: z.ZodObject<{
|
|
|
88
92
|
enabled: boolean;
|
|
89
93
|
uploads: "proxy" | "remote";
|
|
90
94
|
admin: "hide" | "proxy";
|
|
95
|
+
originProtection: {
|
|
96
|
+
requireLogin: boolean;
|
|
97
|
+
};
|
|
91
98
|
themeAssets: string[];
|
|
92
|
-
apiOnly: boolean;
|
|
93
99
|
endpoints: Record<string, string>;
|
|
94
|
-
defaultRevalidate?: number | undefined;
|
|
95
|
-
defaultRevalidateQueries?: number | undefined;
|
|
96
100
|
cors?: {
|
|
97
101
|
origins?: string[] | undefined;
|
|
98
102
|
} | undefined;
|
|
@@ -118,10 +122,10 @@ export declare const EDConfigSchema: z.ZodObject<{
|
|
|
118
122
|
plugins?: "proxy" | "remote" | undefined;
|
|
119
123
|
enabled?: boolean | undefined;
|
|
120
124
|
admin?: "hide" | "proxy" | undefined;
|
|
125
|
+
originProtection?: {
|
|
126
|
+
requireLogin?: boolean | undefined;
|
|
127
|
+
} | undefined;
|
|
121
128
|
themeAssets?: string[] | undefined;
|
|
122
|
-
apiOnly?: boolean | undefined;
|
|
123
|
-
defaultRevalidate?: number | undefined;
|
|
124
|
-
defaultRevalidateQueries?: number | undefined;
|
|
125
129
|
cors?: {
|
|
126
130
|
origins?: string[] | undefined;
|
|
127
131
|
} | undefined;
|
|
@@ -41,17 +41,23 @@ export const EDConfigSchema = z.object({
|
|
|
41
41
|
.enum(["proxy", "hide"])
|
|
42
42
|
.default("proxy")
|
|
43
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."),
|
|
44
|
+
originProtection: z
|
|
45
|
+
.object({
|
|
46
|
+
requireLogin: z
|
|
47
|
+
.boolean()
|
|
48
|
+
.optional()
|
|
49
|
+
.default(false)
|
|
50
|
+
.describe("Enabling this will prevent access to the frontend for non-logged-in users on the CMS origin (eg. Flywheel, WPEngine), but allow access to the serverless frontend (eg. Vercel)."),
|
|
51
|
+
})
|
|
52
|
+
.default({}),
|
|
44
53
|
themeAssets: z
|
|
45
54
|
.array(z.string())
|
|
46
55
|
.optional()
|
|
47
56
|
.default(["assets"])
|
|
48
57
|
.describe('Asset folders to include in a serverless deployment.\nDefault is `["assets"]`'),
|
|
49
|
-
apiOnly: z.boolean().optional().default(false).describe("Whether to deploy only the API, not the frontend"),
|
|
50
58
|
endpoints: z
|
|
51
59
|
.record(z.string(), z.string())
|
|
52
60
|
.describe("A map of WordPress hostnames -> serverless hostnames. You can use `*` as a wildcard for the key.\n\nFor example, `{'cms.ed.studio': 'ed.studio'}` tells the WordPress frontend where it can find any serverless API endpoints."),
|
|
53
|
-
defaultRevalidate: z.number().optional(),
|
|
54
|
-
defaultRevalidateQueries: z.number().optional(),
|
|
55
61
|
cors: z
|
|
56
62
|
.object({
|
|
57
63
|
origins: z
|
|
@@ -66,7 +72,8 @@ export const EDConfigSchema = z.object({
|
|
|
66
72
|
props: z.number(),
|
|
67
73
|
queries: z.number(),
|
|
68
74
|
}))
|
|
69
|
-
.optional()
|
|
75
|
+
.optional()
|
|
76
|
+
.describe("A map of origin domains -> cache settings. Wildcards can be used for each domain."),
|
|
70
77
|
devUI: z.enum(["disabled", "enabled"]).default("enabled"),
|
|
71
78
|
});
|
|
72
79
|
export class Configurator {
|
|
@@ -5,22 +5,26 @@ export declare const fields: {
|
|
|
5
5
|
readonly SITE_URL: z.ZodString;
|
|
6
6
|
readonly DEV_HOT_PORT: z.ZodEffects<z.ZodEffects<z.ZodDefault<z.ZodString>, string | number, string | undefined>, number, string | undefined>;
|
|
7
7
|
readonly DEV_SERVERLESS_PORT: z.ZodEffects<z.ZodEffects<z.ZodDefault<z.ZodString>, string | number, string | undefined>, number, string | undefined>;
|
|
8
|
+
readonly SITE_API_KEY: z.ZodOptional<z.ZodString>;
|
|
8
9
|
};
|
|
9
10
|
export declare const ProjectEnvSchema: z.ZodObject<{
|
|
10
11
|
readonly DEBUG_GRAPHQL_URL: z.ZodOptional<z.ZodString>;
|
|
11
12
|
readonly SITE_URL: z.ZodOptional<z.ZodString>;
|
|
12
13
|
readonly DEV_HOT_PORT: z.ZodOptional<z.ZodEffects<z.ZodEffects<z.ZodDefault<z.ZodString>, string | number, string | undefined>, number, string | undefined>>;
|
|
13
14
|
readonly DEV_SERVERLESS_PORT: z.ZodOptional<z.ZodEffects<z.ZodEffects<z.ZodDefault<z.ZodString>, string | number, string | undefined>, number, string | undefined>>;
|
|
15
|
+
readonly SITE_API_KEY: z.ZodOptional<z.ZodOptional<z.ZodString>>;
|
|
14
16
|
}, "strip", z.ZodTypeAny, {
|
|
15
17
|
DEBUG_GRAPHQL_URL?: string | undefined;
|
|
16
18
|
SITE_URL?: string | undefined;
|
|
17
19
|
DEV_HOT_PORT?: number | undefined;
|
|
18
20
|
DEV_SERVERLESS_PORT?: number | undefined;
|
|
21
|
+
SITE_API_KEY?: string | undefined;
|
|
19
22
|
}, {
|
|
20
23
|
DEBUG_GRAPHQL_URL?: string | undefined;
|
|
21
24
|
SITE_URL?: string | undefined;
|
|
22
25
|
DEV_HOT_PORT?: string | undefined;
|
|
23
26
|
DEV_SERVERLESS_PORT?: string | undefined;
|
|
27
|
+
SITE_API_KEY?: string | undefined;
|
|
24
28
|
}>;
|
|
25
29
|
export type ProjectEnvKey = keyof typeof fields;
|
|
26
30
|
export declare const ProjectEnvUtils: {
|
package/dist/node/project/env.js
CHANGED
|
@@ -15,6 +15,7 @@ export const fields = {
|
|
|
15
15
|
SITE_URL: z.string().url().describe("The URL of the site"),
|
|
16
16
|
DEV_HOT_PORT: portNumber,
|
|
17
17
|
DEV_SERVERLESS_PORT: portNumber,
|
|
18
|
+
SITE_API_KEY: z.string().optional().describe("The API key for the site, when origin protection is enabled"),
|
|
18
19
|
};
|
|
19
20
|
export const ProjectEnvSchema = z.object(fields).partial();
|
|
20
21
|
export const ProjectEnvUtils = {
|
|
@@ -29,6 +29,12 @@ export declare class Project {
|
|
|
29
29
|
private wp;
|
|
30
30
|
reportPluginCompatibility: boolean;
|
|
31
31
|
private constructor();
|
|
32
|
+
verifyOriginAccess(): Promise<{
|
|
33
|
+
success: true;
|
|
34
|
+
} | {
|
|
35
|
+
success: false;
|
|
36
|
+
message: string;
|
|
37
|
+
}>;
|
|
32
38
|
private load;
|
|
33
39
|
reportProjectInfo(): string;
|
|
34
40
|
getWordpressInfo(): Promise<{
|
|
@@ -12,6 +12,7 @@ import { loadRouteManifest } from "./manifest/routes-manifest.js";
|
|
|
12
12
|
import { loadViewManifest } from "./manifest/view-manifest.js";
|
|
13
13
|
import { loadWidgetManifest } from "./manifest/widget-manifest.js";
|
|
14
14
|
import { WPInfo } from "./wp-info.js";
|
|
15
|
+
import { fetchWP } from "../utils/fetch-wp.js";
|
|
15
16
|
const console = createConsole("Project", "project");
|
|
16
17
|
export const projectLog = console;
|
|
17
18
|
/**
|
|
@@ -44,6 +45,34 @@ export class Project {
|
|
|
44
45
|
this.serverRoutes = loadRouteManifest(this);
|
|
45
46
|
this.wp = new WPInfo(this.origin);
|
|
46
47
|
}
|
|
48
|
+
async verifyOriginAccess() {
|
|
49
|
+
try {
|
|
50
|
+
const response = await fetchWP(this.wp.infoUrl);
|
|
51
|
+
if (!response.ok) {
|
|
52
|
+
return {
|
|
53
|
+
success: false,
|
|
54
|
+
message: [
|
|
55
|
+
`Failed to access WordPress origin at ${this.origin}`,
|
|
56
|
+
`Using API Key?: ${ProjectEnvUtils.getSafe("SITE_API_KEY") ? "Yes" : "No"}`,
|
|
57
|
+
`Response: ${response.status} ${response.statusText}`,
|
|
58
|
+
].join("\n"),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
success: true,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
return {
|
|
67
|
+
success: false,
|
|
68
|
+
message: [
|
|
69
|
+
`Failed to access WordPress origin at ${this.origin}`,
|
|
70
|
+
`Using API Key?: ${ProjectEnvUtils.getSafe("SITE_API_KEY") ? "Yes" : "No"}`,
|
|
71
|
+
`The following error occurred:\n${err}`,
|
|
72
|
+
].join("\n"),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
}
|
|
47
76
|
async load() {
|
|
48
77
|
console.setWorking(true);
|
|
49
78
|
console.setState(this);
|
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
import { resolveURL } from "ufo";
|
|
2
|
+
import { fetchWP } from "../utils/fetch-wp.js";
|
|
2
3
|
export class WPInfo {
|
|
3
4
|
siteUrl;
|
|
4
5
|
cached;
|
|
5
6
|
constructor(siteUrl) {
|
|
6
7
|
this.siteUrl = siteUrl;
|
|
7
8
|
}
|
|
9
|
+
get infoUrl() {
|
|
10
|
+
return resolveURL(this.siteUrl, "/wp-json/ed/v1/dev/site-info");
|
|
11
|
+
}
|
|
8
12
|
async getInfo(force = false) {
|
|
9
13
|
if (!this.siteUrl) {
|
|
10
14
|
throw new Error("Attempted to get site info from WordPress, but SITE_URL was not present in the environment.");
|
|
11
15
|
}
|
|
12
16
|
if (this.cached && !force)
|
|
13
17
|
return this.cached;
|
|
14
|
-
const url =
|
|
15
|
-
const response = await
|
|
18
|
+
const url = this.infoUrl;
|
|
19
|
+
const response = await fetchWP(url);
|
|
16
20
|
const result = (await response.json());
|
|
17
21
|
this.cached = result;
|
|
18
22
|
return result;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function fetchWP(url: string | URL, args?: RequestInit): Promise<Response>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ProjectEnvUtils } from "../project/env.js";
|
|
2
|
+
import { Agent, fetch, setGlobalDispatcher, Headers } from "undici";
|
|
3
|
+
const agent = new Agent({
|
|
4
|
+
connect: {
|
|
5
|
+
rejectUnauthorized: false,
|
|
6
|
+
},
|
|
7
|
+
});
|
|
8
|
+
export function fetchWP(url, args = {}) {
|
|
9
|
+
const headers = new Headers(args.headers);
|
|
10
|
+
// If an API key has been set in the environment, use it
|
|
11
|
+
const accessKey = ProjectEnvUtils.getSafe("SITE_API_KEY");
|
|
12
|
+
if (accessKey) {
|
|
13
|
+
headers.set("x-ed-api-key", accessKey);
|
|
14
|
+
}
|
|
15
|
+
// Allow self-signed certificates when using a local development domain
|
|
16
|
+
let allowSelfSigned = isDevelopmentDomain(url);
|
|
17
|
+
return fetch(url, {
|
|
18
|
+
...args,
|
|
19
|
+
dispatcher: allowSelfSigned ? agent : undefined,
|
|
20
|
+
headers,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
setGlobalDispatcher(agent);
|
|
24
|
+
function isDevelopmentDomain(url) {
|
|
25
|
+
const hostname = typeof url === "string" ? new URL(url).hostname : url.hostname;
|
|
26
|
+
return !!hostname?.match(/(^[0-9\.]+$|\.local$)/);
|
|
27
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eddev",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.74",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -106,8 +106,9 @@
|
|
|
106
106
|
"ink-spinner": "^5.0.0",
|
|
107
107
|
"ink-text-input": "^6.0.0",
|
|
108
108
|
"listhen": "^1.6.0",
|
|
109
|
-
"lru-cache": "
|
|
109
|
+
"lru-cache": "10.4.1",
|
|
110
110
|
"mkcert": "^3.2.0",
|
|
111
|
+
"mnemonist": "^0.39.8",
|
|
111
112
|
"obj-console": "^1.0.2",
|
|
112
113
|
"object-code": "^1.3.3",
|
|
113
114
|
"qs": "^6.13.0",
|
|
@@ -116,6 +117,7 @@
|
|
|
116
117
|
"ts-poet": "^6.6.0",
|
|
117
118
|
"ufo": "^1.3.1",
|
|
118
119
|
"undent": "^0.1.0",
|
|
120
|
+
"undici": "^6.21.0",
|
|
119
121
|
"valtio": "^1.13.2",
|
|
120
122
|
"vinxi": "^0.4.3",
|
|
121
123
|
"vite-tsconfig-paths": "^4.2.1",
|