vite-plugin-kiru 0.32.0-preview.1 → 0.32.0-preview.2
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/index.d.ts +19 -0
- package/dist/index.js +1077 -938
- package/dist/server.d.ts +24 -0
- package/dist/server.js +245 -138
- package/package.json +5 -4
package/dist/server.d.ts
CHANGED
|
@@ -14,6 +14,30 @@ export interface ServerRenderOptions {
|
|
|
14
14
|
context: Kiru.RequestContext
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
+
export interface ServerActionsMap {
|
|
18
|
+
[key: string]: () => Promise<unknown>
|
|
19
|
+
}
|
|
20
|
+
|
|
17
21
|
export declare function renderPage(
|
|
18
22
|
options: ServerRenderOptions
|
|
19
23
|
): Promise<SSRRenderResult>
|
|
24
|
+
|
|
25
|
+
export type ServerActionHttpResponse =
|
|
26
|
+
| {
|
|
27
|
+
body: string
|
|
28
|
+
statusCode: 200
|
|
29
|
+
}
|
|
30
|
+
| {
|
|
31
|
+
body: null
|
|
32
|
+
statusCode: 500
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface ServerActionResponse {
|
|
36
|
+
httpResponse: ServerActionHttpResponse | null
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export declare function getServerActionResponse(
|
|
40
|
+
request: Request
|
|
41
|
+
): Promise<ServerActionResponse>
|
|
42
|
+
|
|
43
|
+
export declare function getRequestContext(): Kiru.RequestContext
|
package/dist/server.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// src/server.ts
|
|
2
|
-
import
|
|
3
|
-
import
|
|
2
|
+
import path3 from "node:path";
|
|
3
|
+
import fs2 from "node:fs";
|
|
4
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
4
5
|
|
|
5
6
|
// ../../node_modules/.pnpm/@isaacs+balanced-match@4.0.1/node_modules/@isaacs/balanced-match/dist/esm/index.js
|
|
6
7
|
var balanced = (a, b, str) => {
|
|
@@ -4108,12 +4109,12 @@ var PathBase = class {
|
|
|
4108
4109
|
/**
|
|
4109
4110
|
* Get the Path object referenced by the string path, resolved from this Path
|
|
4110
4111
|
*/
|
|
4111
|
-
resolve(
|
|
4112
|
-
if (!
|
|
4112
|
+
resolve(path4) {
|
|
4113
|
+
if (!path4) {
|
|
4113
4114
|
return this;
|
|
4114
4115
|
}
|
|
4115
|
-
const rootPath = this.getRootString(
|
|
4116
|
-
const dir =
|
|
4116
|
+
const rootPath = this.getRootString(path4);
|
|
4117
|
+
const dir = path4.substring(rootPath.length);
|
|
4117
4118
|
const dirParts = dir.split(this.splitSep);
|
|
4118
4119
|
const result = rootPath ? this.getRoot(rootPath).#resolveParts(dirParts) : this.#resolveParts(dirParts);
|
|
4119
4120
|
return result;
|
|
@@ -4865,8 +4866,8 @@ var PathWin32 = class _PathWin32 extends PathBase {
|
|
|
4865
4866
|
/**
|
|
4866
4867
|
* @internal
|
|
4867
4868
|
*/
|
|
4868
|
-
getRootString(
|
|
4869
|
-
return win32.parse(
|
|
4869
|
+
getRootString(path4) {
|
|
4870
|
+
return win32.parse(path4).root;
|
|
4870
4871
|
}
|
|
4871
4872
|
/**
|
|
4872
4873
|
* @internal
|
|
@@ -4912,8 +4913,8 @@ var PathPosix = class _PathPosix extends PathBase {
|
|
|
4912
4913
|
/**
|
|
4913
4914
|
* @internal
|
|
4914
4915
|
*/
|
|
4915
|
-
getRootString(
|
|
4916
|
-
return
|
|
4916
|
+
getRootString(path4) {
|
|
4917
|
+
return path4.startsWith("/") ? "/" : "";
|
|
4917
4918
|
}
|
|
4918
4919
|
/**
|
|
4919
4920
|
* @internal
|
|
@@ -4962,8 +4963,8 @@ var PathScurryBase = class {
|
|
|
4962
4963
|
*
|
|
4963
4964
|
* @internal
|
|
4964
4965
|
*/
|
|
4965
|
-
constructor(cwd = process.cwd(), pathImpl, sep2, { nocase, childrenCacheSize = 16 * 1024, fs:
|
|
4966
|
-
this.#fs = fsFromOption(
|
|
4966
|
+
constructor(cwd = process.cwd(), pathImpl, sep2, { nocase, childrenCacheSize = 16 * 1024, fs: fs3 = defaultFS } = {}) {
|
|
4967
|
+
this.#fs = fsFromOption(fs3);
|
|
4967
4968
|
if (cwd instanceof URL || cwd.startsWith("file://")) {
|
|
4968
4969
|
cwd = fileURLToPath(cwd);
|
|
4969
4970
|
}
|
|
@@ -5002,11 +5003,11 @@ var PathScurryBase = class {
|
|
|
5002
5003
|
/**
|
|
5003
5004
|
* Get the depth of a provided path, string, or the cwd
|
|
5004
5005
|
*/
|
|
5005
|
-
depth(
|
|
5006
|
-
if (typeof
|
|
5007
|
-
|
|
5006
|
+
depth(path4 = this.cwd) {
|
|
5007
|
+
if (typeof path4 === "string") {
|
|
5008
|
+
path4 = this.cwd.resolve(path4);
|
|
5008
5009
|
}
|
|
5009
|
-
return
|
|
5010
|
+
return path4.depth();
|
|
5010
5011
|
}
|
|
5011
5012
|
/**
|
|
5012
5013
|
* Return the cache of child entries. Exposed so subclasses can create
|
|
@@ -5493,9 +5494,9 @@ var PathScurryBase = class {
|
|
|
5493
5494
|
process2();
|
|
5494
5495
|
return results;
|
|
5495
5496
|
}
|
|
5496
|
-
chdir(
|
|
5497
|
+
chdir(path4 = this.cwd) {
|
|
5497
5498
|
const oldCwd = this.cwd;
|
|
5498
|
-
this.cwd = typeof
|
|
5499
|
+
this.cwd = typeof path4 === "string" ? this.cwd.resolve(path4) : path4;
|
|
5499
5500
|
this.cwd[setAsCwd](oldCwd);
|
|
5500
5501
|
}
|
|
5501
5502
|
};
|
|
@@ -5521,8 +5522,8 @@ var PathScurryWin32 = class extends PathScurryBase {
|
|
|
5521
5522
|
/**
|
|
5522
5523
|
* @internal
|
|
5523
5524
|
*/
|
|
5524
|
-
newRoot(
|
|
5525
|
-
return new PathWin32(this.rootPath, IFDIR, void 0, this.roots, this.nocase, this.childrenCache(), { fs:
|
|
5525
|
+
newRoot(fs3) {
|
|
5526
|
+
return new PathWin32(this.rootPath, IFDIR, void 0, this.roots, this.nocase, this.childrenCache(), { fs: fs3 });
|
|
5526
5527
|
}
|
|
5527
5528
|
/**
|
|
5528
5529
|
* Return true if the provided path string is an absolute path
|
|
@@ -5550,8 +5551,8 @@ var PathScurryPosix = class extends PathScurryBase {
|
|
|
5550
5551
|
/**
|
|
5551
5552
|
* @internal
|
|
5552
5553
|
*/
|
|
5553
|
-
newRoot(
|
|
5554
|
-
return new PathPosix(this.rootPath, IFDIR, void 0, this.roots, this.nocase, this.childrenCache(), { fs:
|
|
5554
|
+
newRoot(fs3) {
|
|
5555
|
+
return new PathPosix(this.rootPath, IFDIR, void 0, this.roots, this.nocase, this.childrenCache(), { fs: fs3 });
|
|
5555
5556
|
}
|
|
5556
5557
|
/**
|
|
5557
5558
|
* Return true if the provided path string is an absolute path
|
|
@@ -5851,8 +5852,8 @@ var MatchRecord = class {
|
|
|
5851
5852
|
}
|
|
5852
5853
|
// match, absolute, ifdir
|
|
5853
5854
|
entries() {
|
|
5854
|
-
return [...this.store.entries()].map(([
|
|
5855
|
-
|
|
5855
|
+
return [...this.store.entries()].map(([path4, n]) => [
|
|
5856
|
+
path4,
|
|
5856
5857
|
!!(n & 2),
|
|
5857
5858
|
!!(n & 1)
|
|
5858
5859
|
]);
|
|
@@ -6057,9 +6058,9 @@ var GlobUtil = class {
|
|
|
6057
6058
|
signal;
|
|
6058
6059
|
maxDepth;
|
|
6059
6060
|
includeChildMatches;
|
|
6060
|
-
constructor(patterns,
|
|
6061
|
+
constructor(patterns, path4, opts) {
|
|
6061
6062
|
this.patterns = patterns;
|
|
6062
|
-
this.path =
|
|
6063
|
+
this.path = path4;
|
|
6063
6064
|
this.opts = opts;
|
|
6064
6065
|
this.#sep = !opts.posix && opts.platform === "win32" ? "\\" : "/";
|
|
6065
6066
|
this.includeChildMatches = opts.includeChildMatches !== false;
|
|
@@ -6078,11 +6079,11 @@ var GlobUtil = class {
|
|
|
6078
6079
|
});
|
|
6079
6080
|
}
|
|
6080
6081
|
}
|
|
6081
|
-
#ignored(
|
|
6082
|
-
return this.seen.has(
|
|
6082
|
+
#ignored(path4) {
|
|
6083
|
+
return this.seen.has(path4) || !!this.#ignore?.ignored?.(path4);
|
|
6083
6084
|
}
|
|
6084
|
-
#childrenIgnored(
|
|
6085
|
-
return !!this.#ignore?.childrenIgnored?.(
|
|
6085
|
+
#childrenIgnored(path4) {
|
|
6086
|
+
return !!this.#ignore?.childrenIgnored?.(path4);
|
|
6086
6087
|
}
|
|
6087
6088
|
// backpressure mechanism
|
|
6088
6089
|
pause() {
|
|
@@ -6297,8 +6298,8 @@ var GlobUtil = class {
|
|
|
6297
6298
|
};
|
|
6298
6299
|
var GlobWalker = class extends GlobUtil {
|
|
6299
6300
|
matches = /* @__PURE__ */ new Set();
|
|
6300
|
-
constructor(patterns,
|
|
6301
|
-
super(patterns,
|
|
6301
|
+
constructor(patterns, path4, opts) {
|
|
6302
|
+
super(patterns, path4, opts);
|
|
6302
6303
|
}
|
|
6303
6304
|
matchEmit(e) {
|
|
6304
6305
|
this.matches.add(e);
|
|
@@ -6335,8 +6336,8 @@ var GlobWalker = class extends GlobUtil {
|
|
|
6335
6336
|
};
|
|
6336
6337
|
var GlobStream = class extends GlobUtil {
|
|
6337
6338
|
results;
|
|
6338
|
-
constructor(patterns,
|
|
6339
|
-
super(patterns,
|
|
6339
|
+
constructor(patterns, path4, opts) {
|
|
6340
|
+
super(patterns, path4, opts);
|
|
6340
6341
|
this.results = new Minipass({
|
|
6341
6342
|
signal: this.signal,
|
|
6342
6343
|
objectMode: true
|
|
@@ -6662,57 +6663,140 @@ var VIRTUAL_ENTRY_SERVER_ID = "virtual:kiru:entry-server";
|
|
|
6662
6663
|
var VIRTUAL_ENTRY_CLIENT_ID = "virtual:kiru:entry-client";
|
|
6663
6664
|
|
|
6664
6665
|
// src/globals.ts
|
|
6665
|
-
|
|
6666
|
-
|
|
6666
|
+
import path2 from "node:path";
|
|
6667
|
+
import fs from "node:fs";
|
|
6668
|
+
var $KIRU_SERVER_GLOBAL = Symbol.for("kiru.server.global");
|
|
6669
|
+
var projectRoot = process.cwd().replace(/\\/g, "/");
|
|
6670
|
+
var serverOutDirAbs = path2.resolve(projectRoot, "dist/server");
|
|
6671
|
+
var manifestPath = path2.resolve(serverOutDirAbs, "vite-manifest.json");
|
|
6672
|
+
var global = globalThis[$KIRU_SERVER_GLOBAL] ??= {
|
|
6667
6673
|
viteDevServer: null,
|
|
6668
|
-
|
|
6674
|
+
serverEntryModule: Promise.withResolvers(),
|
|
6675
|
+
route: null,
|
|
6676
|
+
loadedRemoteModules: /* @__PURE__ */ new Map()
|
|
6669
6677
|
};
|
|
6670
|
-
|
|
6671
|
-
get
|
|
6672
|
-
|
|
6673
|
-
|
|
6674
|
-
|
|
6675
|
-
|
|
6678
|
+
async function loadRouteRemoteModule(route) {
|
|
6679
|
+
const existing = global.loadedRemoteModules.get(route);
|
|
6680
|
+
if (existing) return existing;
|
|
6681
|
+
const {
|
|
6682
|
+
config: { remotes }
|
|
6683
|
+
} = await getServerEntryModule();
|
|
6684
|
+
const routeEntry = remotes[route];
|
|
6685
|
+
if (!routeEntry) {
|
|
6686
|
+
throw new Error(`Remote functions route not found: ${route}`);
|
|
6687
|
+
}
|
|
6688
|
+
const promise = remotes[route].load();
|
|
6689
|
+
global.loadedRemoteModules.set(route, promise);
|
|
6690
|
+
return promise;
|
|
6691
|
+
}
|
|
6692
|
+
var serverEntryLoadInitialized = false;
|
|
6693
|
+
async function getServerEntryModule() {
|
|
6694
|
+
if (process.env.NODE_ENV === "production" && !serverEntryLoadInitialized) {
|
|
6695
|
+
serverEntryLoadInitialized = true;
|
|
6696
|
+
loadServerEntryModuleFromBuild();
|
|
6676
6697
|
}
|
|
6677
|
-
|
|
6678
|
-
|
|
6679
|
-
|
|
6680
|
-
|
|
6681
|
-
|
|
6682
|
-
|
|
6683
|
-
|
|
6684
|
-
global.serverEntry = server;
|
|
6685
|
-
if (server) {
|
|
6686
|
-
entryServerResolvers.forEach((fn) => fn());
|
|
6687
|
-
entryServerResolvers = [];
|
|
6688
|
-
}
|
|
6698
|
+
return global.serverEntryModule.promise;
|
|
6699
|
+
}
|
|
6700
|
+
async function loadServerEntryModuleFromBuild() {
|
|
6701
|
+
if (!fs.existsSync(manifestPath)) {
|
|
6702
|
+
throw new Error(
|
|
6703
|
+
`Server manifest not found at ${manifestPath}. Make sure the SSR build has been completed.`
|
|
6704
|
+
);
|
|
6689
6705
|
}
|
|
6690
|
-
|
|
6691
|
-
|
|
6692
|
-
|
|
6693
|
-
|
|
6694
|
-
|
|
6695
|
-
|
|
6696
|
-
|
|
6697
|
-
|
|
6698
|
-
|
|
6699
|
-
|
|
6700
|
-
|
|
6701
|
-
|
|
6702
|
-
|
|
6703
|
-
|
|
6704
|
-
|
|
6706
|
+
const manifest = JSON.parse(
|
|
6707
|
+
fs.readFileSync(manifestPath, "utf-8")
|
|
6708
|
+
);
|
|
6709
|
+
const virtualEntryServerModule = Object.values(manifest).find(
|
|
6710
|
+
(value) => value.src === VIRTUAL_ENTRY_SERVER_ID
|
|
6711
|
+
);
|
|
6712
|
+
if (!virtualEntryServerModule) {
|
|
6713
|
+
throw new Error(
|
|
6714
|
+
"Virtual entry server module not found in manifest. Make sure the SSR build has been completed."
|
|
6715
|
+
);
|
|
6716
|
+
}
|
|
6717
|
+
const entryServerFile = virtualEntryServerModule.file;
|
|
6718
|
+
const entryServerPath = path2.resolve(serverOutDirAbs, entryServerFile);
|
|
6719
|
+
if (!fs.existsSync(entryServerPath)) {
|
|
6720
|
+
throw new Error(
|
|
6721
|
+
`Virtual entry server module file not found at ${entryServerPath}`
|
|
6722
|
+
);
|
|
6723
|
+
}
|
|
6724
|
+
const fileUrl = `file://${entryServerPath.replace(/\\/g, "/")}`;
|
|
6725
|
+
const mod = await import(
|
|
6726
|
+
/* @vite-ignore */
|
|
6727
|
+
fileUrl
|
|
6728
|
+
);
|
|
6729
|
+
global.serverEntryModule.resolve(mod);
|
|
6730
|
+
}
|
|
6731
|
+
|
|
6732
|
+
// src/token.ts
|
|
6733
|
+
import crypto from "crypto";
|
|
6734
|
+
function makeKiruContextToken(ctx, secret) {
|
|
6735
|
+
const iat = Date.now();
|
|
6736
|
+
const payload = {
|
|
6737
|
+
iat,
|
|
6738
|
+
ctx
|
|
6739
|
+
};
|
|
6740
|
+
if (!secret) throw new Error("secret required");
|
|
6741
|
+
return createSignedTokenHmac(payload, secret);
|
|
6742
|
+
}
|
|
6743
|
+
function unwrapKiruToken(token, secret) {
|
|
6744
|
+
const payload = verifySignedTokenHmac(token, secret);
|
|
6745
|
+
if (!payload) return null;
|
|
6746
|
+
return payload.ctx;
|
|
6747
|
+
}
|
|
6748
|
+
function createSignedTokenHmac(payload, secret) {
|
|
6749
|
+
const header = { alg: "HS256", typ: "KRT" };
|
|
6750
|
+
const headerB = Buffer.from(JSON.stringify(header), "utf8");
|
|
6751
|
+
const payloadB = Buffer.from(JSON.stringify(payload), "utf8");
|
|
6752
|
+
const signingInput = `${base64UrlEncode(headerB)}.${base64UrlEncode(
|
|
6753
|
+
payloadB
|
|
6754
|
+
)}`;
|
|
6755
|
+
const signature = crypto.createHmac("sha256", secret).update(signingInput).digest();
|
|
6756
|
+
return `${signingInput}.${base64UrlEncode(signature)}`;
|
|
6757
|
+
}
|
|
6758
|
+
function verifySignedTokenHmac(token, secret) {
|
|
6759
|
+
try {
|
|
6760
|
+
const parts = token.split(".");
|
|
6761
|
+
if (parts.length !== 3) return null;
|
|
6762
|
+
const [headerB64, payloadB64, sigB64] = parts;
|
|
6763
|
+
const header = JSON.parse(
|
|
6764
|
+
Buffer.from(headerB64, "base64").toString("utf8")
|
|
6765
|
+
);
|
|
6766
|
+
if (header.typ !== "KRT") return null;
|
|
6767
|
+
if (header.alg !== "HS256") return null;
|
|
6768
|
+
const signingInput = `${headerB64}.${payloadB64}`;
|
|
6769
|
+
const expectedSig = crypto.createHmac("sha256", secret).update(signingInput).digest();
|
|
6770
|
+
const sig = base64UrlDecode(sigB64);
|
|
6771
|
+
if (!crypto.timingSafeEqual(expectedSig, sig)) return null;
|
|
6772
|
+
const payload = JSON.parse(
|
|
6773
|
+
Buffer.from(payloadB64, "base64").toString("utf8")
|
|
6774
|
+
);
|
|
6775
|
+
return payload;
|
|
6776
|
+
} catch (e) {
|
|
6777
|
+
return null;
|
|
6778
|
+
}
|
|
6779
|
+
}
|
|
6780
|
+
function base64UrlEncode(buf) {
|
|
6781
|
+
const b64 = Buffer.from(buf).toString("base64");
|
|
6782
|
+
return b64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
6783
|
+
}
|
|
6784
|
+
function base64UrlDecode(s) {
|
|
6785
|
+
s = s.replace(/-/g, "+").replace(/_/g, "/");
|
|
6786
|
+
while (s.length % 4) s += "=";
|
|
6787
|
+
return Buffer.from(s, "base64");
|
|
6705
6788
|
}
|
|
6706
6789
|
|
|
6707
6790
|
// src/server.ts
|
|
6708
|
-
|
|
6791
|
+
var als = new AsyncLocalStorage();
|
|
6792
|
+
async function getClientAssets(clientOutDirAbs, manifestPath2) {
|
|
6709
6793
|
let clientEntry = null;
|
|
6710
6794
|
let manifest = null;
|
|
6711
6795
|
try {
|
|
6712
|
-
const clientManifestPath =
|
|
6713
|
-
if (
|
|
6796
|
+
const clientManifestPath = path3.resolve(clientOutDirAbs, manifestPath2);
|
|
6797
|
+
if (fs2.existsSync(clientManifestPath)) {
|
|
6714
6798
|
const parsedManifest = JSON.parse(
|
|
6715
|
-
|
|
6799
|
+
fs2.readFileSync(clientManifestPath, "utf-8")
|
|
6716
6800
|
);
|
|
6717
6801
|
manifest = parsedManifest;
|
|
6718
6802
|
if (parsedManifest[VIRTUAL_ENTRY_CLIENT_ID]?.file) {
|
|
@@ -6723,7 +6807,7 @@ async function getClientAssets(clientOutDirAbs, manifestPath) {
|
|
|
6723
6807
|
}
|
|
6724
6808
|
return { clientEntry, manifest };
|
|
6725
6809
|
}
|
|
6726
|
-
function collectCssForModules(manifest, moduleIds,
|
|
6810
|
+
function collectCssForModules(manifest, moduleIds, projectRoot2) {
|
|
6727
6811
|
if (!manifest) return "";
|
|
6728
6812
|
const seen = /* @__PURE__ */ new Set();
|
|
6729
6813
|
const cssFiles = /* @__PURE__ */ new Set();
|
|
@@ -6745,8 +6829,8 @@ function collectCssForModules(manifest, moduleIds, projectRoot) {
|
|
|
6745
6829
|
}
|
|
6746
6830
|
for (const moduleId of moduleIds) {
|
|
6747
6831
|
let normalizedId = moduleId.replace(/\\/g, "/");
|
|
6748
|
-
if (normalizedId.startsWith(
|
|
6749
|
-
normalizedId = normalizedId.substring(
|
|
6832
|
+
if (normalizedId.startsWith(projectRoot2)) {
|
|
6833
|
+
normalizedId = normalizedId.substring(projectRoot2.length);
|
|
6750
6834
|
}
|
|
6751
6835
|
if (normalizedId.startsWith("/")) {
|
|
6752
6836
|
normalizedId = normalizedId.substring(1);
|
|
@@ -6765,8 +6849,8 @@ function collectCssForModules(manifest, moduleIds, projectRoot) {
|
|
|
6765
6849
|
}
|
|
6766
6850
|
for (const key in manifestRef) {
|
|
6767
6851
|
const keyNormalized = key.replace(/\\/g, "/");
|
|
6768
|
-
const moduleBaseName =
|
|
6769
|
-
const keyBaseName =
|
|
6852
|
+
const moduleBaseName = path3.basename(normalizedId);
|
|
6853
|
+
const keyBaseName = path3.basename(keyNormalized);
|
|
6770
6854
|
if ((keyNormalized.endsWith(normalizedId) || normalizedId.endsWith(keyNormalized)) && moduleBaseName === keyBaseName) {
|
|
6771
6855
|
collectCss(key);
|
|
6772
6856
|
break;
|
|
@@ -6779,58 +6863,11 @@ function collectCssForModules(manifest, moduleIds, projectRoot) {
|
|
|
6779
6863
|
}
|
|
6780
6864
|
return "";
|
|
6781
6865
|
}
|
|
6782
|
-
async function resolveServerRenderer() {
|
|
6783
|
-
if (process.env.NODE_ENV !== "production") {
|
|
6784
|
-
return awaitServerRendererInitialized_Dev();
|
|
6785
|
-
}
|
|
6786
|
-
return loadServerRenderer_Production();
|
|
6787
|
-
}
|
|
6788
|
-
async function loadServerRenderer_Production() {
|
|
6789
|
-
const projectRoot = process.cwd().replace(/\\/g, "/");
|
|
6790
|
-
const serverOutDirAbs = path2.resolve(projectRoot, "dist/server");
|
|
6791
|
-
const manifestPath = path2.resolve(serverOutDirAbs, "vite-manifest.json");
|
|
6792
|
-
if (!fs.existsSync(manifestPath)) {
|
|
6793
|
-
throw new Error(
|
|
6794
|
-
`Server manifest not found at ${manifestPath}. Make sure the SSR build has been completed.`
|
|
6795
|
-
);
|
|
6796
|
-
}
|
|
6797
|
-
const manifest = JSON.parse(
|
|
6798
|
-
fs.readFileSync(manifestPath, "utf-8")
|
|
6799
|
-
);
|
|
6800
|
-
const virtualEntryServerModule = Object.values(manifest).find(
|
|
6801
|
-
(value) => value.src === VIRTUAL_ENTRY_SERVER_ID
|
|
6802
|
-
);
|
|
6803
|
-
if (!virtualEntryServerModule) {
|
|
6804
|
-
throw new Error(
|
|
6805
|
-
"Virtual entry server module not found in manifest. Make sure the SSR build has been completed."
|
|
6806
|
-
);
|
|
6807
|
-
}
|
|
6808
|
-
const entryServerFile = virtualEntryServerModule.file;
|
|
6809
|
-
const entryServerPath = path2.resolve(serverOutDirAbs, entryServerFile);
|
|
6810
|
-
if (!fs.existsSync(entryServerPath)) {
|
|
6811
|
-
throw new Error(
|
|
6812
|
-
`Virtual entry server module file not found at ${entryServerPath}`
|
|
6813
|
-
);
|
|
6814
|
-
}
|
|
6815
|
-
const fileUrl = `file://${entryServerPath.replace(/\\/g, "/")}`;
|
|
6816
|
-
const module = await import(
|
|
6817
|
-
/* @vite-ignore */
|
|
6818
|
-
fileUrl
|
|
6819
|
-
);
|
|
6820
|
-
if (!module.render || !module.documentModuleId) {
|
|
6821
|
-
throw new Error(
|
|
6822
|
-
"Virtual entry server module does not export render and documentModuleId"
|
|
6823
|
-
);
|
|
6824
|
-
}
|
|
6825
|
-
return {
|
|
6826
|
-
render: module.render,
|
|
6827
|
-
documentModuleId: module.documentModuleId
|
|
6828
|
-
};
|
|
6829
|
-
}
|
|
6830
6866
|
async function renderPage(options) {
|
|
6831
|
-
const { render, documentModuleId } = await
|
|
6867
|
+
const { render, documentModuleId, remoteFunctionSecret } = await getServerEntryModule();
|
|
6832
6868
|
const moduleIds = [documentModuleId];
|
|
6833
|
-
const
|
|
6869
|
+
const projectRoot2 = process.cwd().replace(/\\/g, "/");
|
|
6870
|
+
als.enterWith(options.context);
|
|
6834
6871
|
const { httpResponse } = await render(options.url, {
|
|
6835
6872
|
userContext: options.context,
|
|
6836
6873
|
registerModule(moduleId) {
|
|
@@ -6838,9 +6875,7 @@ async function renderPage(options) {
|
|
|
6838
6875
|
}
|
|
6839
6876
|
});
|
|
6840
6877
|
if (httpResponse === null) {
|
|
6841
|
-
return {
|
|
6842
|
-
httpResponse: null
|
|
6843
|
-
};
|
|
6878
|
+
return { httpResponse: null };
|
|
6844
6879
|
}
|
|
6845
6880
|
const isDevelopment = process.env.NODE_ENV !== "production";
|
|
6846
6881
|
let html = httpResponse.html;
|
|
@@ -6859,8 +6894,8 @@ async function renderPage(options) {
|
|
|
6859
6894
|
}
|
|
6860
6895
|
};
|
|
6861
6896
|
for (const id of moduleIds) {
|
|
6862
|
-
const p =
|
|
6863
|
-
const mod =
|
|
6897
|
+
const p = path3.join(projectRoot2, id).replace(/\\/g, "/");
|
|
6898
|
+
const mod = global.viteDevServer.moduleGraph.getModuleById(p);
|
|
6864
6899
|
if (!mod) {
|
|
6865
6900
|
console.error(`Module not found: ${p}`);
|
|
6866
6901
|
continue;
|
|
@@ -6868,24 +6903,24 @@ async function renderPage(options) {
|
|
|
6868
6903
|
scan(mod);
|
|
6869
6904
|
}
|
|
6870
6905
|
const localModules = Array.from(importedModules).filter(
|
|
6871
|
-
(m) => m.id?.startsWith(
|
|
6906
|
+
(m) => m.id?.startsWith(projectRoot2)
|
|
6872
6907
|
);
|
|
6873
6908
|
const cssModules = localModules.filter((m) => m.id?.endsWith(".css"));
|
|
6874
6909
|
if (cssModules.length) {
|
|
6875
6910
|
const stylesheets = cssModules.map((mod) => {
|
|
6876
|
-
const p = mod.id?.replace(
|
|
6911
|
+
const p = mod.id?.replace(projectRoot2, "");
|
|
6877
6912
|
return `<link rel="stylesheet" type="text/css" href="${p}?temp">`;
|
|
6878
6913
|
});
|
|
6879
6914
|
html = html.replace("<head>", "<head>" + stylesheets.join("\n"));
|
|
6880
6915
|
}
|
|
6881
6916
|
} else {
|
|
6882
|
-
const clientOutDirAbs =
|
|
6917
|
+
const clientOutDirAbs = path3.resolve(projectRoot2, "dist/client");
|
|
6883
6918
|
const { clientEntry, manifest } = await getClientAssets(
|
|
6884
6919
|
clientOutDirAbs,
|
|
6885
6920
|
"vite-manifest.json"
|
|
6886
6921
|
);
|
|
6887
6922
|
if (manifest) {
|
|
6888
|
-
const cssLinks = collectCssForModules(manifest, moduleIds,
|
|
6923
|
+
const cssLinks = collectCssForModules(manifest, moduleIds, projectRoot2);
|
|
6889
6924
|
if (cssLinks) {
|
|
6890
6925
|
html = html.replace("<head>", "<head>" + cssLinks);
|
|
6891
6926
|
}
|
|
@@ -6900,6 +6935,14 @@ async function renderPage(options) {
|
|
|
6900
6935
|
"</head>",
|
|
6901
6936
|
`<script type="application/json" k-request-context>${contextString}</script></head>`
|
|
6902
6937
|
);
|
|
6938
|
+
const token = makeKiruContextToken(
|
|
6939
|
+
options.context,
|
|
6940
|
+
remoteFunctionSecret
|
|
6941
|
+
);
|
|
6942
|
+
html = html.replace(
|
|
6943
|
+
"</head>",
|
|
6944
|
+
`<script type="application/json" k-request-token>${token}</script></head>`
|
|
6945
|
+
);
|
|
6903
6946
|
return {
|
|
6904
6947
|
httpResponse: {
|
|
6905
6948
|
...httpResponse,
|
|
@@ -6907,6 +6950,70 @@ async function renderPage(options) {
|
|
|
6907
6950
|
}
|
|
6908
6951
|
};
|
|
6909
6952
|
}
|
|
6953
|
+
async function getServerActionResponse(request) {
|
|
6954
|
+
let action;
|
|
6955
|
+
let actionArgs = [];
|
|
6956
|
+
let context;
|
|
6957
|
+
const { searchParams } = new URL(request.url);
|
|
6958
|
+
try {
|
|
6959
|
+
let strToken, actionId;
|
|
6960
|
+
if (request.method !== "POST" || request.headers.get("Content-Type") !== "application/json" || !(strToken = request.headers.get("x-kiru-token")) || !(actionId = searchParams.get("action"))) {
|
|
6961
|
+
return { httpResponse: null };
|
|
6962
|
+
}
|
|
6963
|
+
const [route, actionName] = actionId.split(".");
|
|
6964
|
+
await loadRouteRemoteModule(route);
|
|
6965
|
+
const {
|
|
6966
|
+
config: { actions },
|
|
6967
|
+
remoteFunctionSecret
|
|
6968
|
+
} = await getServerEntryModule();
|
|
6969
|
+
const ctx = unwrapKiruToken(strToken, remoteFunctionSecret);
|
|
6970
|
+
if (!ctx) {
|
|
6971
|
+
return createBadActionResponse();
|
|
6972
|
+
}
|
|
6973
|
+
const fileActions = actions.get(route);
|
|
6974
|
+
const actionFn = fileActions[actionName];
|
|
6975
|
+
const args = await request.json();
|
|
6976
|
+
if (typeof actionFn !== "function" || !Array.isArray(args)) {
|
|
6977
|
+
return createBadActionResponse();
|
|
6978
|
+
}
|
|
6979
|
+
action = actionFn;
|
|
6980
|
+
actionArgs = args;
|
|
6981
|
+
context = ctx;
|
|
6982
|
+
} catch {
|
|
6983
|
+
return createBadActionResponse();
|
|
6984
|
+
}
|
|
6985
|
+
return new Promise(async (resolve) => {
|
|
6986
|
+
als.run({ ...context }, async () => {
|
|
6987
|
+
try {
|
|
6988
|
+
const result = await action(...actionArgs);
|
|
6989
|
+
resolve({
|
|
6990
|
+
httpResponse: {
|
|
6991
|
+
body: JSON.stringify(result),
|
|
6992
|
+
statusCode: 200
|
|
6993
|
+
}
|
|
6994
|
+
});
|
|
6995
|
+
} catch {
|
|
6996
|
+
resolve(createBadActionResponse());
|
|
6997
|
+
}
|
|
6998
|
+
});
|
|
6999
|
+
});
|
|
7000
|
+
}
|
|
7001
|
+
function createBadActionResponse() {
|
|
7002
|
+
return {
|
|
7003
|
+
httpResponse: { body: null, statusCode: 500 }
|
|
7004
|
+
};
|
|
7005
|
+
}
|
|
7006
|
+
function getRequestContext() {
|
|
7007
|
+
const ctx = als.getStore();
|
|
7008
|
+
if (ctx === void 0) {
|
|
7009
|
+
throw new Error(
|
|
7010
|
+
"[vite-plugin-kiru]: Invalid `getRequestContext` invocation."
|
|
7011
|
+
);
|
|
7012
|
+
}
|
|
7013
|
+
return ctx;
|
|
7014
|
+
}
|
|
6910
7015
|
export {
|
|
7016
|
+
getRequestContext,
|
|
7017
|
+
getServerActionResponse,
|
|
6911
7018
|
renderPage
|
|
6912
7019
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vite-plugin-kiru",
|
|
3
|
-
"version": "0.32.0-preview.
|
|
3
|
+
"version": "0.32.0-preview.2",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
}
|
|
20
20
|
},
|
|
21
21
|
"peerDependencies": {
|
|
22
|
-
"kiru": ">=0.54.0-preview.
|
|
22
|
+
"kiru": ">=0.54.0-preview.1"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"@types/node": "^22.17.0",
|
|
@@ -27,14 +27,15 @@
|
|
|
27
27
|
"rollup": "^4.46.2",
|
|
28
28
|
"tsx": "^4.20.3",
|
|
29
29
|
"typescript": "^5.9.2",
|
|
30
|
-
"kiru-devtools-client": "^0.0.0",
|
|
31
30
|
"kiru-devtools-host": "^1.0.0",
|
|
32
|
-
"kiru": "^0.
|
|
31
|
+
"kiru-devtools-client": "^0.0.0",
|
|
32
|
+
"kiru": "^0.54.0-preview.1"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"glob": "^12.0.0",
|
|
36
36
|
"magic-string": "^0.30.17",
|
|
37
37
|
"mime": "^4.1.0",
|
|
38
|
+
"minimatch": "10.1.1",
|
|
38
39
|
"vite": "^7.2.2"
|
|
39
40
|
},
|
|
40
41
|
"scripts": {
|