eddev 2.0.0-beta.4 → 2.0.0-beta.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app/entry/MetaTags.d.ts +7 -0
- package/dist/app/entry/MetaTags.js +17 -0
- package/dist/app/entry/boot-admin.d.ts +1 -0
- package/dist/app/entry/{main.admin.js → boot-admin.js} +3 -5
- package/dist/app/entry/spa-root.d.ts +1 -0
- package/dist/app/entry/{Root.js → spa-root.js} +4 -4
- package/dist/app/entry/ssr-root-client.d.ts +6 -0
- package/dist/app/entry/ssr-root-client.js +16 -0
- package/dist/app/entry/ssr-root.d.ts +10 -0
- package/dist/app/entry/ssr-root.js +24 -0
- package/dist/app/lib/admin/index.d.ts +2 -2
- package/dist/app/lib/admin/index.js +2 -2
- package/dist/app/lib/admin/installFieldTypes.js +1 -1
- package/dist/app/lib/admin/runWidgets.js +1 -1
- package/dist/app/lib/blocks/ContentBlocks.js +4 -4
- package/dist/app/lib/blocks/EditableText.d.ts +1 -1
- package/dist/app/lib/blocks/EditableText.js +3 -3
- package/dist/app/lib/blocks/ErrorBoundaryFrontend.js +1 -0
- package/dist/app/lib/blocks/InnerBlocks.d.ts +13 -3
- package/dist/app/lib/blocks/InnerBlocks.js +13 -5
- package/dist/app/lib/blocks/block-utils.d.ts +2 -2
- package/dist/app/lib/blocks/block-utils.js +2 -2
- package/dist/app/lib/blocks/editor/EditorSupport.js +3 -3
- package/dist/app/lib/blocks/editor/editor-config.d.ts +1 -1
- package/dist/app/lib/blocks/editor/editor-config.js +1 -1
- package/dist/app/lib/blocks/editor/installGutenbergHooks.js +5 -5
- package/dist/app/lib/blocks/editor/usePostEditor.d.ts +1 -1
- package/dist/app/lib/blocks/index.d.ts +9 -9
- package/dist/app/lib/blocks/index.js +9 -9
- package/dist/app/lib/blocks/inline-editing.d.ts +1 -1
- package/dist/app/lib/blocks/inline-editing.js +7 -5
- package/dist/app/lib/devtools/components/BreakpointIndicator.js +6 -4
- package/dist/app/lib/devtools/components/DevUI.js +4 -3
- package/dist/app/lib/devtools/components/GridIndicator.d.ts +1 -0
- package/dist/app/lib/devtools/components/GridIndicator.js +24 -0
- package/dist/app/lib/devtools/dev-tools-store.d.ts +9 -0
- package/dist/app/lib/devtools/dev-tools-store.js +8 -0
- package/dist/app/lib/devtools/hooks/usePersistState.d.ts +1 -1
- package/dist/app/lib/devtools/hooks/usePersistState.js +11 -2
- package/dist/app/lib/devtools/hooks/useTailwind.d.ts +1078 -1079
- package/dist/app/lib/devtools/hooks/useTailwind.js +6 -3
- package/dist/app/lib/devtools/index.d.ts +1 -0
- package/dist/app/lib/devtools/index.js +1 -1
- package/dist/app/lib/devtools/loader.js +8 -7
- package/dist/app/lib/devtools/useQueryDebug.d.ts +7 -1
- package/dist/app/lib/devtools/useQueryDebug.js +5 -8
- package/dist/app/lib/dynamic/index.d.ts +1 -1
- package/dist/app/lib/dynamic/index.js +1 -1
- package/dist/app/lib/hooks/apiConfig.d.ts +3 -1
- package/dist/app/lib/hooks/apiConfig.js +9 -4
- package/dist/app/lib/hooks/index.d.ts +4 -5
- package/dist/app/lib/hooks/index.js +4 -5
- package/dist/app/lib/hooks/queryUtils.d.ts +5 -2
- package/dist/app/lib/hooks/queryUtils.js +19 -20
- package/dist/app/lib/hooks/useAppData.js +1 -1
- package/dist/app/lib/internal/index.d.ts +4 -4
- package/dist/app/lib/internal/index.js +4 -4
- package/dist/app/lib/internal/internal-store.d.ts +0 -2
- package/dist/app/lib/internal/internal-store.js +1 -3
- package/dist/app/lib/internal/read-admin-manifest.d.ts +1 -1
- package/dist/app/lib/legacy-stitches/createStitches.d.ts +21 -21
- package/dist/app/lib/legacy-stitches/createStitches.js +1 -1
- package/dist/app/lib/legacy-stitches/index.d.ts +1 -1
- package/dist/app/lib/legacy-stitches/index.js +1 -1
- package/dist/app/lib/routing/components/BackButton.d.ts +49 -0
- package/dist/app/lib/routing/components/BackButton.js +47 -0
- package/dist/app/lib/routing/components/BrowserRouter.d.ts +4 -1
- package/dist/app/lib/routing/components/BrowserRouter.js +68 -11
- package/dist/app/lib/routing/components/ClientOnly.js +1 -1
- package/dist/app/lib/routing/components/Link.d.ts +1 -0
- package/dist/app/lib/routing/components/Link.js +9 -10
- package/dist/app/lib/routing/components/RouteRenderer.d.ts +1 -1
- package/dist/app/lib/routing/components/RouteRenderer.js +7 -6
- package/dist/app/lib/routing/components/SSRRouter.d.ts +2 -2
- package/dist/app/lib/routing/components/SSRRouter.js +5 -6
- package/dist/app/lib/routing/components/ScrollRestoration.js +1 -1
- package/dist/app/lib/routing/context.d.ts +2 -2
- package/dist/app/lib/routing/context.js +6 -96
- package/dist/app/lib/routing/hooks/useRestorableState.js +2 -1
- package/dist/app/lib/routing/hooks/useRoute.d.ts +16 -1
- package/dist/app/lib/routing/hooks/useRoute.js +22 -1
- package/dist/app/lib/routing/hooks/useRouteMeta.d.ts +5 -0
- package/dist/app/lib/routing/hooks/useRouteMeta.js +9 -0
- package/dist/app/lib/routing/hooks/useRouteTransition.d.ts +1 -1
- package/dist/app/lib/routing/hooks/useRouteTransition.js +1 -1
- package/dist/app/lib/routing/hooks/useRouter.d.ts +1 -1
- package/dist/app/lib/routing/hooks/useRouter.js +1 -1
- package/dist/app/lib/routing/hooks/useRouterEvents.d.ts +1 -1
- package/dist/app/lib/routing/hooks/useRouterEvents.js +1 -1
- package/dist/app/lib/routing/hooks/useRouterState.d.ts +1 -1
- package/dist/app/lib/routing/hooks/useRouterState.js +1 -1
- package/dist/app/lib/routing/hooks/useSearchParams.js +2 -2
- package/dist/app/lib/routing/index.d.ts +14 -13
- package/dist/app/lib/routing/index.js +14 -13
- package/dist/app/lib/routing/loader.d.ts +2 -2
- package/dist/app/lib/routing/loader.js +7 -5
- package/dist/app/lib/routing/types.d.ts +28 -8
- package/dist/app/lib/routing/utils.d.ts +3 -1
- package/dist/app/lib/routing/utils.js +11 -0
- package/dist/app/lib/views/index.d.ts +1 -1
- package/dist/app/lib/views/index.js +1 -1
- package/dist/app/server/defineRouter.d.ts +2 -0
- package/dist/app/server/defineRouter.js +4 -0
- package/dist/app/server/index.d.ts +4 -0
- package/dist/app/server/index.js +4 -0
- package/dist/app/server/proxy-wp-admin.d.ts +3 -0
- package/dist/app/server/proxy-wp-admin.js +105 -0
- package/dist/app/server/render-ssr-page.d.ts +5 -0
- package/dist/app/server/render-ssr-page.js +31 -0
- package/dist/app/server/server-context.d.ts +50 -0
- package/dist/app/server/server-context.js +145 -0
- package/dist/app/server/utils/headers.d.ts +1 -0
- package/dist/app/server/utils/headers.js +17 -0
- package/dist/app/server/utils/replace-host.d.ts +6 -4
- package/dist/app/server/utils/replace-host.js +58 -11
- package/dist/node/cli/cli-worker.d.ts +1 -1
- package/dist/node/cli/cli-worker.js +7 -2
- package/dist/node/cli/cli.js +84 -12
- package/dist/node/cli/display/CLIApp.d.ts +1 -1
- package/dist/node/cli/display/CLIApp.js +3 -6
- package/dist/node/cli/display/components/LogEntries.d.ts +1 -1
- package/dist/node/cli/display/hooks/useStatefulLog.d.ts +1 -1
- package/dist/node/cli/display/tools/CreateBlock.d.ts +1 -1
- package/dist/node/cli/display/tools/cli-tools.d.ts +1 -11
- package/dist/node/cli/display/tools/cli-tools.js +9 -9
- package/dist/node/cli/display/util/colors.d.ts +2 -2
- package/dist/node/cli/version.d.ts +1 -1
- package/dist/node/cli/version.js +1 -1
- package/dist/node/compiler/build-vinxi.d.ts +8 -0
- package/dist/node/compiler/build-vinxi.js +37 -0
- package/dist/node/compiler/bundler.admin.d.ts +2 -2
- package/dist/node/compiler/bundler.admin.js +3 -4
- package/dist/node/compiler/bundler.frontend.d.ts +1 -1
- package/dist/node/compiler/bundler.frontend.js +3 -4
- package/dist/node/compiler/{serverless.dev.d.ts → dev-server.d.ts} +7 -5
- package/dist/node/compiler/dev-server.js +105 -0
- package/dist/node/compiler/get-vite-config.d.ts +19 -0
- package/dist/node/compiler/get-vite-config.js +200 -0
- package/dist/node/compiler/vinxi-app.d.ts +19 -0
- package/dist/node/compiler/vinxi-app.js +159 -0
- package/dist/node/compiler/vinxi-codegen.d.ts +12 -0
- package/dist/node/compiler/vinxi-codegen.js +464 -0
- package/dist/node/graphql/graphql-codegen.d.ts +1 -1
- package/dist/node/graphql/graphql-codegen.js +63 -16
- package/dist/node/graphql/graphql-schema-loader.js +15 -18
- package/dist/node/project/config.js +1 -1
- package/dist/node/project/env.d.ts +1 -1
- package/dist/node/project/env.js +1 -1
- package/dist/node/project/manifest/block-manifest.js +2 -2
- package/dist/node/project/manifest/manifest.d.ts +1 -1
- package/dist/node/project/manifest/manifest.js +1 -1
- package/dist/node/project/manifest/view-manifest.js +2 -2
- package/dist/node/project/project.d.ts +3 -2
- package/dist/node/project/project.js +18 -20
- package/dist/node/project/wp-info.js +3 -2
- package/dist/node/types/view-type.js +3 -4
- package/dist/node/utils/fs-codegen.d.ts +40 -0
- package/dist/node/utils/fs-codegen.js +97 -0
- package/dist/node/utils/fs.js +2 -0
- package/dist/node/utils/{selfSignedCert.js → self-signed-cert.js} +1 -1
- package/dist/node/utils/{statefulLog.js → stateful-log.js} +1 -1
- package/package.json +31 -32
- package/types.app.d.ts +2 -2
- package/types.app.internal.d.ts +2 -2
- package/types.node.d.ts +3 -3
- package/dist/app/entry/Root.d.ts +0 -1
- package/dist/app/entry/main.admin.d.ts +0 -3
- package/dist/app/entry/main.frontend.spa.d.ts +0 -3
- package/dist/app/entry/main.frontend.spa.js +0 -13
- package/dist/app/entry/main.frontend.ssr.d.ts +0 -21
- package/dist/app/entry/main.frontend.ssr.js +0 -79
- package/dist/app/entry/main.serverless.dev.d.ts +0 -4
- package/dist/app/entry/main.serverless.dev.js +0 -21
- package/dist/app/lib/hooks/usePageLoad.d.ts +0 -6
- package/dist/app/lib/hooks/usePageLoad.js +0 -5
- package/dist/app/server/create-api-builtin-hono.d.ts +0 -8
- package/dist/app/server/create-api-builtin-hono.js +0 -80
- package/dist/app/server/create-ssr-hono.d.ts +0 -18
- package/dist/app/server/create-ssr-hono.js +0 -104
- package/dist/app/server/utils/index.html.d.ts +0 -2
- package/dist/app/server/utils/index.html.js +0 -14
- package/dist/node/compiler/index.html.d.ts +0 -2
- package/dist/node/compiler/index.html.js +0 -15
- package/dist/node/compiler/serverless.dev.js +0 -215
- package/dist/node/compiler/vite/get-vite-config.d.ts +0 -13
- package/dist/node/compiler/vite/get-vite-config.js +0 -323
- package/dist/node/compiler/vite/plugin-admin.d.ts +0 -4
- package/dist/node/compiler/vite/plugin-admin.js +0 -67
- package/dist/node/compiler/vite/plugin-blocks.d.ts +0 -4
- package/dist/node/compiler/vite/plugin-blocks.js +0 -73
- package/dist/node/compiler/vite/plugin-entry.d.ts +0 -6
- package/dist/node/compiler/vite/plugin-entry.js +0 -16
- package/dist/node/compiler/vite/plugin-resolved-tailwind.d.ts +0 -4
- package/dist/node/compiler/vite/plugin-resolved-tailwind.js +0 -29
- package/dist/node/compiler/vite/plugin-theme.d.ts +0 -4
- package/dist/node/compiler/vite/plugin-theme.js +0 -40
- package/dist/node/compiler/vite/plugin-views.d.ts +0 -4
- package/dist/node/compiler/vite/plugin-views.js +0 -51
- package/dist/node/utils/console.d.ts +0 -21
- package/dist/node/utils/console.js +0 -28
- package/dist/node/utils/unsafe-fetch.d.ts +0 -2
- package/dist/node/utils/unsafe-fetch.js +0 -19
- package/tsup.config.ts +0 -40
- package/types.manifests.d.ts +0 -22
- /package/dist/node/utils/{formatZodError.d.ts → format-zod-error.d.ts} +0 -0
- /package/dist/node/utils/{formatZodError.js → format-zod-error.js} +0 -0
- /package/dist/node/utils/{getRepoInfo.d.ts → get-repo-info.d.ts} +0 -0
- /package/dist/node/utils/{getRepoInfo.js → get-repo-info.js} +0 -0
- /package/dist/node/utils/{highlightCode.d.ts → highlight-code.d.ts} +0 -0
- /package/dist/node/utils/{highlightCode.js → highlight-code.js} +0 -0
- /package/dist/node/utils/{isDeploying.d.ts → is-deploying.d.ts} +0 -0
- /package/dist/node/utils/{isDeploying.js → is-deploying.js} +0 -0
- /package/dist/node/utils/{selfSignedCert.d.ts → self-signed-cert.d.ts} +0 -0
- /package/dist/node/utils/{statefulLog.d.ts → stateful-log.d.ts} +0 -0
- /package/dist/node/utils/{export-extractor.d.ts → ts-export-extractor.d.ts} +0 -0
- /package/dist/node/utils/{export-extractor.js → ts-export-extractor.js} +0 -0
- /package/dist/node/utils/{watchFileTree.d.ts → watch-file-tree.d.ts} +0 -0
- /package/dist/node/utils/{watchFileTree.js → watch-file-tree.js} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { parseURL, stringifyParsedURL, stringifyQuery, withTrailingSlash } from "ufo";
|
|
2
|
-
import { viewManifestReader } from "../internal";
|
|
2
|
+
import { viewManifestReader } from "../internal/read-view-manifest.js";
|
|
3
3
|
export class RouteError extends Error {
|
|
4
4
|
message;
|
|
5
5
|
statusCode;
|
|
@@ -31,10 +31,12 @@ export class RouteLoader {
|
|
|
31
31
|
const origin = parseURL(sampleUrl);
|
|
32
32
|
let propsPath = withTrailingSlash(pathname);
|
|
33
33
|
let query = {};
|
|
34
|
-
if (
|
|
35
|
-
|
|
36
|
-
query
|
|
37
|
-
query["
|
|
34
|
+
if (env.serverless && env.client) {
|
|
35
|
+
propsPath = "/_data/route" + propsPath;
|
|
36
|
+
query = {};
|
|
37
|
+
// query["_debug"] = opts.debug ? "1" : "0"
|
|
38
|
+
// query["_props"] = opts.appData ? "all" : "1"
|
|
39
|
+
// query["_ssr"] = "1"
|
|
38
40
|
}
|
|
39
41
|
else {
|
|
40
42
|
query["_debug"] = opts.debug ? "1" : "0";
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import { FunctionComponent } from "react";
|
|
2
|
-
import type { RouteLoader } from "./loader";
|
|
3
|
-
import { LinkHandlerMode, PointerOrMouseEvent } from "./utils";
|
|
4
|
-
export type
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
import type { RouteLoader } from "./loader.js";
|
|
3
|
+
import { LinkHandlerMode, PointerOrMouseEvent } from "./utils.js";
|
|
4
|
+
export type RouteMetaTag = {
|
|
5
|
+
tagName: string;
|
|
6
|
+
attributes: Record<string, string>;
|
|
7
|
+
inner?: string;
|
|
8
|
+
};
|
|
9
|
+
export type TrackerTags = {
|
|
10
|
+
head?: RouteMetaTag[];
|
|
11
|
+
body?: RouteMetaTag[];
|
|
12
|
+
footer?: RouteMetaTag[];
|
|
13
|
+
};
|
|
7
14
|
export interface RouteData {
|
|
8
15
|
view: string;
|
|
9
16
|
editLink?: string;
|
|
@@ -13,10 +20,13 @@ export interface RouteData {
|
|
|
13
20
|
redirect?: string;
|
|
14
21
|
canonical?: string;
|
|
15
22
|
meta?: {
|
|
16
|
-
head:
|
|
17
|
-
footer:
|
|
23
|
+
head: RouteMetaTag[];
|
|
24
|
+
footer: RouteMetaTag[];
|
|
18
25
|
};
|
|
19
26
|
}
|
|
27
|
+
export interface RouteDataWithTrackers extends RouteData {
|
|
28
|
+
trackers?: TrackerTags;
|
|
29
|
+
}
|
|
20
30
|
export type RouteReturnState<T = {}> = {
|
|
21
31
|
scrollTop: number;
|
|
22
32
|
scrollLeft: number;
|
|
@@ -100,13 +110,17 @@ export type RouterAPI = {
|
|
|
100
110
|
/** Replace the hash */
|
|
101
111
|
replaceHash: (hash: string) => void;
|
|
102
112
|
/** Handle link clicking events */
|
|
103
|
-
handleClickEvent(e: PointerOrMouseEvent, href?: string): void;
|
|
113
|
+
handleClickEvent(e: PointerOrMouseEvent, href?: string, preferBack?: boolean | "exact"): void;
|
|
104
114
|
/** A reference to the route loader (mostly for internal use) */
|
|
105
115
|
loader: RouteLoader;
|
|
106
116
|
/** Subscribe to events */
|
|
107
117
|
subscribe: (subscribe: RouterSubscriber) => () => void;
|
|
108
118
|
/** This function is used by the routing system automatically */
|
|
109
119
|
emitEvent: (event: RouterEvent) => void;
|
|
120
|
+
/** Returns the current RouterState */
|
|
121
|
+
getState: () => RouterAPIState | null;
|
|
122
|
+
/** Go back to a previous route in the history stack, or push it onto the stack if it isn't currently on the stack. */
|
|
123
|
+
restoreRoute: (route: RouteState) => void;
|
|
110
124
|
};
|
|
111
125
|
export type TypedRouteState<T, TProps> = {
|
|
112
126
|
/** A unique ID, representing this history item. */
|
|
@@ -131,6 +145,12 @@ export type TypedRouteState<T, TProps> = {
|
|
|
131
145
|
component: FunctionComponent<TProps>;
|
|
132
146
|
/** The props for this route, to be passed to the component. */
|
|
133
147
|
props: TProps;
|
|
148
|
+
/** Loaded metadata for this route */
|
|
149
|
+
meta: RouteMeta;
|
|
150
|
+
};
|
|
151
|
+
export type RouteMeta = {
|
|
152
|
+
title?: string;
|
|
153
|
+
tags?: RouteMetaTag[];
|
|
134
154
|
};
|
|
135
155
|
export type RouteState = {
|
|
136
156
|
[K in keyof ViewProps]: TypedRouteState<K, ViewProps[K]>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { MouseEvent as ReactMouseEvent, PointerEvent as ReactPointerEvent } from "react";
|
|
2
|
-
import { RouteLink, RouteState } from "./types";
|
|
2
|
+
import { RouteData, RouteLink, RouteMeta, RouteState } from "./types.js";
|
|
3
3
|
export declare function isSameOrigin(url: string): boolean;
|
|
4
|
+
export declare function isSamePathname(a: string, b: string): boolean;
|
|
4
5
|
export type PointerOrMouseEvent = MouseEvent | PointerEvent | ReactMouseEvent | ReactPointerEvent;
|
|
5
6
|
export type LinkHandlerMode = {
|
|
6
7
|
mode: "ignore" | "navigate" | "native";
|
|
@@ -12,4 +13,5 @@ export declare function normalizeRoute(route: Partialize<RouteState, "uri" | "re
|
|
|
12
13
|
export declare function stringifyRouteLink(route: RouteLink): string;
|
|
13
14
|
export declare function parseQuery(query: string): Record<string, string | string[]>;
|
|
14
15
|
export declare function stringifyQuery(query: any): string;
|
|
16
|
+
export declare function getRouteMeta(data: RouteData): RouteMeta;
|
|
15
17
|
export {};
|
|
@@ -10,6 +10,11 @@ export function isSameOrigin(url) {
|
|
|
10
10
|
return parsed.protocol === document.location.protocol && parsed.host === document.location.host;
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
|
+
export function isSamePathname(a, b) {
|
|
14
|
+
const left = parseURL(a).pathname.replace(/\/$/, "").toLocaleLowerCase();
|
|
15
|
+
const right = parseURL(b).pathname.replace(/\/$/, "").toLocaleLowerCase();
|
|
16
|
+
return left === right;
|
|
17
|
+
}
|
|
13
18
|
export function getLinkHandlerMode(e, href) {
|
|
14
19
|
try {
|
|
15
20
|
// Attempt to get the link element, if there is one
|
|
@@ -92,3 +97,9 @@ export function stringifyQuery(query) {
|
|
|
92
97
|
arrayFormat: "brackets",
|
|
93
98
|
});
|
|
94
99
|
}
|
|
100
|
+
export function getRouteMeta(data) {
|
|
101
|
+
return {
|
|
102
|
+
title: data.meta?.head.find((tag) => tag.tagName === "title")?.inner,
|
|
103
|
+
tags: data.meta?.head ?? [],
|
|
104
|
+
};
|
|
105
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from "./defineView";
|
|
1
|
+
export * from "./defineView.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from "./defineView";
|
|
1
|
+
export * from "./defineView.js";
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/// <reference types="vinxi/types/server" />
|
|
2
|
+
import { splitSetCookieString } from "cookie-es";
|
|
3
|
+
import { getProxyRequestHeaders, getRequestURL, getWebRequest } from "vinxi/http";
|
|
4
|
+
export async function proxyWpAdmin(event, serverContext) {
|
|
5
|
+
const replaceUrls = serverContext.replaceUrls;
|
|
6
|
+
const req = getWebRequest(event);
|
|
7
|
+
const proxyUrl = serverContext.getOriginUrl(getRequestURL(event).href);
|
|
8
|
+
// Prepare request headers to be sent to the origin server
|
|
9
|
+
const proxyHeaders = getProxyRequestHeaders(event);
|
|
10
|
+
proxyHeaders["X-ED-Dev-Proxy"] = "true";
|
|
11
|
+
// Forward the request to the origin server
|
|
12
|
+
const response = await fetch(proxyUrl, {
|
|
13
|
+
method: req.method,
|
|
14
|
+
referrer: req.referrer,
|
|
15
|
+
referrerPolicy: req.referrerPolicy,
|
|
16
|
+
headers: proxyHeaders,
|
|
17
|
+
body: req.method.match(/get|head|options/i) ? undefined : await req.blob(),
|
|
18
|
+
redirect: "manual",
|
|
19
|
+
cache: "no-cache",
|
|
20
|
+
});
|
|
21
|
+
const contentType = response.headers.get("content-type");
|
|
22
|
+
let body;
|
|
23
|
+
let res = { status: response.status, statusText: response.statusText, headers: new Headers() };
|
|
24
|
+
const cookies = [];
|
|
25
|
+
response.headers.forEach((value, key) => {
|
|
26
|
+
if (key === "content-encoding" || key === "content-length" || key === "transfer-encoding") {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
if (key === "set-cookie") {
|
|
30
|
+
cookies.push(...splitSetCookieString(value));
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
if (key === "location" && replaceUrls) {
|
|
34
|
+
value = replaceUrls(value);
|
|
35
|
+
}
|
|
36
|
+
res.headers.set(key, value);
|
|
37
|
+
});
|
|
38
|
+
// Set cookies in the response headers
|
|
39
|
+
// TODO: May need to rewrite cookie domain here before setting.
|
|
40
|
+
if (cookies.length > 0) {
|
|
41
|
+
for (const cookie of cookies) {
|
|
42
|
+
res.headers.append("set-cookie", cookie);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// Replace URLs pointing to the origin server from the response itself
|
|
46
|
+
// This is only done for text-based content types, like application/json, text/plain, text/html etc
|
|
47
|
+
if (contentType?.match(/(application|text)\//)) {
|
|
48
|
+
if (replaceUrls) {
|
|
49
|
+
body = replaceUrls((await response.text()) ?? "");
|
|
50
|
+
}
|
|
51
|
+
// If the content type is text/html, inject the Vite assets into the response — assuming the placeholder comments are found
|
|
52
|
+
if (contentType.startsWith("text/html")) {
|
|
53
|
+
const clientManifest = serverContext.runtime.getManifest("admin");
|
|
54
|
+
const assets = await clientManifest.inputs[clientManifest.handler].assets();
|
|
55
|
+
body = body.replace("<!---VITE_HEADER--->", () => assets.map((asset) => renderAsset(asset)).join("\n"));
|
|
56
|
+
body = body.replace("<!---VITE_FOOTER--->", () => renderAsset({
|
|
57
|
+
tag: "script",
|
|
58
|
+
attrs: {
|
|
59
|
+
type: "module",
|
|
60
|
+
src: clientManifest.inputs[clientManifest.handler].output.path,
|
|
61
|
+
},
|
|
62
|
+
children: "",
|
|
63
|
+
}));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
// Otherwise just stream the response as is
|
|
68
|
+
body = response.body;
|
|
69
|
+
}
|
|
70
|
+
return new Response(body, res);
|
|
71
|
+
}
|
|
72
|
+
function printElement(element, props, innerText) {
|
|
73
|
+
if (typeof innerText === "string") {
|
|
74
|
+
return `<${element}${Object.entries(props)
|
|
75
|
+
.map(([key, value]) => ` ${key}="${value}"`)
|
|
76
|
+
.join("")}>${innerText}</${element}>`;
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
return `<${element}${Object.entries(props)
|
|
80
|
+
.map(([key, value]) => ` ${key}="${value}"`)
|
|
81
|
+
.join("")} />`;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function renderAsset({ tag, attrs: { key, ...attrs } = {}, children, }) {
|
|
85
|
+
switch (tag) {
|
|
86
|
+
case "script":
|
|
87
|
+
if (attrs.src) {
|
|
88
|
+
return printElement("script", { ...attrs, key: attrs.src }, "");
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
return printElement("script", {
|
|
92
|
+
...attrs,
|
|
93
|
+
key: key,
|
|
94
|
+
}, children ?? "");
|
|
95
|
+
}
|
|
96
|
+
case "link":
|
|
97
|
+
return printElement("link", { ...attrs, key: key });
|
|
98
|
+
case "style":
|
|
99
|
+
return printElement("style", {
|
|
100
|
+
...attrs,
|
|
101
|
+
key: key,
|
|
102
|
+
}, children ?? "");
|
|
103
|
+
}
|
|
104
|
+
return "";
|
|
105
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { RouteData, TrackerTags } from "../lib/routing/types.js";
|
|
2
|
+
import { ServerContext } from "./server-context.js";
|
|
3
|
+
export declare function renderPageToSSRStream(pathname: string, initialData: RouteData & {
|
|
4
|
+
trackers?: TrackerTags;
|
|
5
|
+
}, serverContext: ServerContext): Promise<unknown>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { renderAsset } from "@vinxi/react";
|
|
3
|
+
import { Suspense } from "react";
|
|
4
|
+
import { renderToPipeableStream } from "react-dom/server";
|
|
5
|
+
import { SSRRoot } from "../entry/ssr-root.js";
|
|
6
|
+
import { RouteLoader } from "../lib/routing/loader.js";
|
|
7
|
+
export async function renderPageToSSRStream(pathname, initialData, serverContext) {
|
|
8
|
+
const clientManifest = serverContext.runtime.getManifest("client");
|
|
9
|
+
const assets = await clientManifest.inputs[clientManifest.handler].assets();
|
|
10
|
+
const jsx = (_jsx(SSRRoot, { assets: _jsx(Suspense, { children: assets.map((m) => renderAsset(m)) }), metaTags: initialData?.meta?.head || [], pathname: pathname, initialData: initialData, loader: new RouteLoader() }));
|
|
11
|
+
const stream = await new Promise(async (resolve, reject) => {
|
|
12
|
+
// console.log("Rendering to pipable")
|
|
13
|
+
const stream = renderToPipeableStream(jsx, {
|
|
14
|
+
onShellReady() {
|
|
15
|
+
// console.log("Shell ready")
|
|
16
|
+
resolve(stream);
|
|
17
|
+
},
|
|
18
|
+
onShellError(err) {
|
|
19
|
+
console.log("onShellError", err);
|
|
20
|
+
resolve("An error occurred");
|
|
21
|
+
},
|
|
22
|
+
onError(err, errInfo) {
|
|
23
|
+
console.log("Error occurred after shell ready", err, errInfo);
|
|
24
|
+
console.error(err);
|
|
25
|
+
},
|
|
26
|
+
bootstrapModules: [clientManifest.inputs[clientManifest.handler].output.path],
|
|
27
|
+
bootstrapScriptContent: `window.manifest = ${JSON.stringify(await clientManifest.json())};\nwindow._PAGE_DATA = ${JSON.stringify(initialData)};`,
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
return stream;
|
|
31
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { RequestHeaders } from "vinxi/http";
|
|
2
|
+
import { UrlReplacerConf } from "./utils/replace-host.js";
|
|
3
|
+
import { Manifest } from "vinxi/dist/types/types/manifest";
|
|
4
|
+
import { TrackerTags } from "../lib/routing/types.js";
|
|
5
|
+
export type ServerContextArgs = {
|
|
6
|
+
dev: boolean;
|
|
7
|
+
origin: string;
|
|
8
|
+
replaceUrls?: UrlReplacerConf;
|
|
9
|
+
};
|
|
10
|
+
export type ServerContextRuntime = {
|
|
11
|
+
getManifest: (name: string) => Manifest;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Data returned from WordPress origin /_appdata route
|
|
15
|
+
*/
|
|
16
|
+
type ServerAppData = {
|
|
17
|
+
appData: any;
|
|
18
|
+
trackers: TrackerTags;
|
|
19
|
+
};
|
|
20
|
+
export declare class ServerContext {
|
|
21
|
+
dev: boolean;
|
|
22
|
+
origin: string;
|
|
23
|
+
replaceUrls?: (text: string) => string;
|
|
24
|
+
constructor(conf: ServerContextArgs);
|
|
25
|
+
get runtime(): ServerContextRuntime;
|
|
26
|
+
static setRuntime(rt: ServerContextRuntime): void;
|
|
27
|
+
getOriginUrl(url: string): string;
|
|
28
|
+
fetchOrigin(url: string, opts?: RequestInit & {
|
|
29
|
+
replaceUrls?: boolean;
|
|
30
|
+
}): Promise<Response>;
|
|
31
|
+
fetchRouteData(req: {
|
|
32
|
+
pathname: string;
|
|
33
|
+
query?: Record<string, any>;
|
|
34
|
+
headers?: RequestHeaders;
|
|
35
|
+
withAppData?: boolean;
|
|
36
|
+
}): Promise<Response>;
|
|
37
|
+
fetchAppData(): Promise<ServerAppData>;
|
|
38
|
+
extractRequestHeaders(req?: RequestHeaders): Partial<Record<import("vinxi/http").HTTPHeaderName, string | undefined>>;
|
|
39
|
+
fetchNamedQuery(req: {
|
|
40
|
+
name: string;
|
|
41
|
+
params: object;
|
|
42
|
+
headers: RequestHeaders;
|
|
43
|
+
}): Promise<Response>;
|
|
44
|
+
fetchMutation(req: {
|
|
45
|
+
name: string;
|
|
46
|
+
body: object;
|
|
47
|
+
headers: RequestHeaders;
|
|
48
|
+
}): Promise<Response>;
|
|
49
|
+
}
|
|
50
|
+
export {};
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { parseURL, stringifyParsedURL, withQuery } from "ufo";
|
|
2
|
+
import { filterHeader } from "./utils/headers.js";
|
|
3
|
+
import { createUrlReplacer } from "./utils/replace-host.js";
|
|
4
|
+
const PROXY_RESPONSE_HEADERS = ["content-type", "set-cookie", /^x-/, "cache-control", /woocommerce/];
|
|
5
|
+
const PROXY_REQUEST_HEADERS = [
|
|
6
|
+
"content-type",
|
|
7
|
+
"accept",
|
|
8
|
+
"accept-encoding",
|
|
9
|
+
"accept-language",
|
|
10
|
+
"origin",
|
|
11
|
+
"referer",
|
|
12
|
+
"user-agent",
|
|
13
|
+
"authorization",
|
|
14
|
+
"woocommerce-session",
|
|
15
|
+
];
|
|
16
|
+
let runtime;
|
|
17
|
+
export class ServerContext {
|
|
18
|
+
dev;
|
|
19
|
+
origin;
|
|
20
|
+
replaceUrls;
|
|
21
|
+
constructor(conf) {
|
|
22
|
+
this.dev = conf.dev;
|
|
23
|
+
this.origin = conf.origin;
|
|
24
|
+
if (conf.replaceUrls) {
|
|
25
|
+
this.replaceUrls = createUrlReplacer(conf.replaceUrls);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
get runtime() {
|
|
29
|
+
return runtime;
|
|
30
|
+
}
|
|
31
|
+
static setRuntime(rt) {
|
|
32
|
+
runtime = rt;
|
|
33
|
+
}
|
|
34
|
+
getOriginUrl(url) {
|
|
35
|
+
const parsed = parseURL(url);
|
|
36
|
+
const parsedOrigin = parseURL(this.origin);
|
|
37
|
+
parsed.host = parsedOrigin.host;
|
|
38
|
+
parsed.protocol = parsedOrigin.protocol;
|
|
39
|
+
return stringifyParsedURL(parsed);
|
|
40
|
+
}
|
|
41
|
+
async fetchOrigin(url, opts) {
|
|
42
|
+
url = this.getOriginUrl(url);
|
|
43
|
+
const response = await fetch(url, {
|
|
44
|
+
...opts,
|
|
45
|
+
headers: {
|
|
46
|
+
"Content-Type": "application/json",
|
|
47
|
+
Accept: "application/json",
|
|
48
|
+
...opts?.headers,
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
if (!response.ok) {
|
|
52
|
+
return response;
|
|
53
|
+
}
|
|
54
|
+
// console.log("Response headers", response.headers)
|
|
55
|
+
const headers = {};
|
|
56
|
+
response.headers.forEach((value, key) => {
|
|
57
|
+
if (filterHeader(key, PROXY_RESPONSE_HEADERS)) {
|
|
58
|
+
headers[key] = value;
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
// console.log("Returning headers", headers)
|
|
62
|
+
let text = await response.text();
|
|
63
|
+
if (opts?.replaceUrls && this.replaceUrls) {
|
|
64
|
+
text = this.replaceUrls(text);
|
|
65
|
+
}
|
|
66
|
+
return new Response(text, {
|
|
67
|
+
status: response.status,
|
|
68
|
+
statusText: response.statusText,
|
|
69
|
+
headers,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
async fetchRouteData(req) {
|
|
73
|
+
const fetchUrl = withQuery(req.pathname, {
|
|
74
|
+
...req.query,
|
|
75
|
+
_props: "1",
|
|
76
|
+
_ssr: "1",
|
|
77
|
+
_debug: this.dev ? "1" : undefined,
|
|
78
|
+
});
|
|
79
|
+
// console.log("Fetching route data", req.pathname)
|
|
80
|
+
const result = this.fetchOrigin(fetchUrl, {
|
|
81
|
+
cache: "no-cache",
|
|
82
|
+
replaceUrls: true,
|
|
83
|
+
headers: {
|
|
84
|
+
"Content-Type": "application/json",
|
|
85
|
+
Accept: "application/json",
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
// console.log("Finished fetching route data")
|
|
89
|
+
return result;
|
|
90
|
+
}
|
|
91
|
+
async fetchAppData() {
|
|
92
|
+
// console.log("Fetching app data")
|
|
93
|
+
const response = await this.fetchOrigin("/_appdata", {
|
|
94
|
+
cache: "no-cache",
|
|
95
|
+
replaceUrls: true,
|
|
96
|
+
headers: {
|
|
97
|
+
"Content-Type": "application/json",
|
|
98
|
+
Accept: "application/json",
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
// console.log("Decoding app data")
|
|
102
|
+
const result = await response.json();
|
|
103
|
+
// console.log("Done with app done")
|
|
104
|
+
return result;
|
|
105
|
+
}
|
|
106
|
+
extractRequestHeaders(req) {
|
|
107
|
+
const headers = {};
|
|
108
|
+
if (req) {
|
|
109
|
+
for (let key of PROXY_REQUEST_HEADERS) {
|
|
110
|
+
if (req[key]) {
|
|
111
|
+
headers[key] = req[key];
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return headers;
|
|
116
|
+
}
|
|
117
|
+
async fetchNamedQuery(req) {
|
|
118
|
+
const url = `/wp-json/ed/v1/query/${req.name}?params=${encodeURIComponent(JSON.stringify(req.params))}`;
|
|
119
|
+
return this.fetchOrigin(url, {
|
|
120
|
+
cache: "no-cache",
|
|
121
|
+
replaceUrls: true,
|
|
122
|
+
headers: {
|
|
123
|
+
...this.extractRequestHeaders(req.headers),
|
|
124
|
+
"Content-Type": "application/json",
|
|
125
|
+
Accept: "application/json",
|
|
126
|
+
},
|
|
127
|
+
redirect: "manual",
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
async fetchMutation(req) {
|
|
131
|
+
const url = `/wp-json/ed/v1/mutation/${req.name}`;
|
|
132
|
+
return this.fetchOrigin(url, {
|
|
133
|
+
method: "POST",
|
|
134
|
+
cache: "no-cache",
|
|
135
|
+
replaceUrls: true,
|
|
136
|
+
headers: {
|
|
137
|
+
...this.extractRequestHeaders(req.headers),
|
|
138
|
+
"Content-Type": "application/json",
|
|
139
|
+
Accept: "application/json",
|
|
140
|
+
},
|
|
141
|
+
body: JSON.stringify(req.body),
|
|
142
|
+
redirect: "manual",
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}
|
|
@@ -9,3 +9,20 @@ export function filterHeader(key, allowed) {
|
|
|
9
9
|
export const BRANDED_HEADERS = {
|
|
10
10
|
"X-Powered-By": "ed.studio",
|
|
11
11
|
};
|
|
12
|
+
const IGNORE_REQUEST_HEADERS = [
|
|
13
|
+
"host",
|
|
14
|
+
"connection",
|
|
15
|
+
"accept-encoding",
|
|
16
|
+
"accept-language",
|
|
17
|
+
"origin",
|
|
18
|
+
"referer",
|
|
19
|
+
"user-agent",
|
|
20
|
+
];
|
|
21
|
+
export function extractHeaders(rawHeaders) {
|
|
22
|
+
const headers = {};
|
|
23
|
+
rawHeaders.forEach((value, key) => {
|
|
24
|
+
headers[key] = value;
|
|
25
|
+
});
|
|
26
|
+
IGNORE_REQUEST_HEADERS.forEach((key) => delete headers[key]);
|
|
27
|
+
return headers;
|
|
28
|
+
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
export type UrlReplacerConf = {
|
|
2
2
|
from: string;
|
|
3
3
|
to: string;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
/** A dictionary of prefixes (eg /wp-content), and whether to replace them (true/false) */
|
|
5
|
+
prefixes: {
|
|
6
|
+
prefix: string;
|
|
7
|
+
replace: boolean;
|
|
8
|
+
}[];
|
|
7
9
|
};
|
|
8
|
-
export declare function createUrlReplacer(conf: UrlReplacerConf): (
|
|
10
|
+
export declare function createUrlReplacer(conf: UrlReplacerConf): (text: string) => string;
|
|
@@ -1,14 +1,61 @@
|
|
|
1
1
|
export function createUrlReplacer(conf) {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
2
|
+
// Create a regular expression to match the URL
|
|
3
|
+
// Note that that the regex doesn't necessarily match the entire URL
|
|
4
|
+
const lookup = new RegExp(conf.from.replace(/https?[:\\\/]+/, "https?[:\\/\\\\]+") + "([a-z0-9\\-_/\\\\]+)", "ig");
|
|
5
|
+
return (text) => {
|
|
6
|
+
return text.replace(lookup, (url) => {
|
|
7
|
+
// Strip out the origin, to create a relative path
|
|
8
|
+
const path = url.replace(/https?:[\/\\]+[^\/\\]+/, "");
|
|
9
|
+
const isEscaped = url.includes(":\\/\\/");
|
|
10
|
+
const key = "/" +
|
|
11
|
+
path
|
|
12
|
+
.split(/[\/\\]+/g)
|
|
13
|
+
.filter((v) => v)
|
|
14
|
+
.join("/");
|
|
15
|
+
for (let item of conf.prefixes) {
|
|
16
|
+
if (key.startsWith(item.prefix)) {
|
|
17
|
+
if (item.replace) {
|
|
18
|
+
return url;
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
return path;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return path;
|
|
26
|
+
// if (path.startsWith("/wp-content/uploads/")) {
|
|
27
|
+
// if (!conf.ignoreUploads) {
|
|
28
|
+
// return path
|
|
29
|
+
// } else {
|
|
30
|
+
// return url
|
|
31
|
+
// }
|
|
32
|
+
// // } else if (path.startsWith("/wp-content/themes/")) {
|
|
33
|
+
// // if (settings?.uploads === "proxy") {
|
|
34
|
+
// // return path
|
|
35
|
+
// // } else if (settings?.uploads === "remote") {
|
|
36
|
+
// // return url
|
|
37
|
+
// // }
|
|
38
|
+
// // } else if (path.startsWith("/wp-content/plugins/")) {
|
|
39
|
+
// // if (settings?.uploads === "proxy") {
|
|
40
|
+
// // return path
|
|
41
|
+
// // } else if (settings?.uploads === "remote") {
|
|
42
|
+
// // return url
|
|
43
|
+
// // }
|
|
44
|
+
// } else {
|
|
45
|
+
// return path
|
|
46
|
+
// }
|
|
47
|
+
});
|
|
13
48
|
};
|
|
49
|
+
// const from = conf.from
|
|
50
|
+
// const to = conf.to
|
|
51
|
+
// const https = conf.https
|
|
52
|
+
// const ignoreUploads = conf.ignoreUploads
|
|
53
|
+
// const ignorePlugins = conf.ignorePlugins
|
|
54
|
+
// const replaceTargetString = from.replaceAll(/https?:/g, "https?:").replaceAll("/", "\\/")
|
|
55
|
+
// const replaceTargetEscapedString = from.replaceAll(/https?:/g, "https?:").replaceAll("/", "\\\\/")
|
|
56
|
+
// const replaceTarget = new RegExp(replaceTargetString, "g")
|
|
57
|
+
// const replaceTargetEscaped = new RegExp(replaceTargetEscapedString, "g")
|
|
58
|
+
// return (value: string) => {
|
|
59
|
+
// return value.replaceAll(replaceTarget, to).replace(replaceTargetEscaped, to.replaceAll("/", "\\/"))
|
|
60
|
+
// }
|
|
14
61
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Worker } from "node:worker_threads";
|
|
2
|
-
import { StatefulLog } from "../utils/
|
|
2
|
+
import { StatefulLog } from "../utils/stateful-log.js";
|
|
3
3
|
type WorkerMode = "admin" | "frontend" | "graphql" | "serverless";
|
|
4
4
|
export declare class CLIWorker {
|
|
5
5
|
worker: Worker;
|