@rpcbase/server 0.513.0 → 0.514.0
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/{email-DEw8keax.js → email-DK8uUU4X.js} +5 -2
- package/dist/{email-DEw8keax.js.map → email-DK8uUU4X.js.map} +1 -1
- package/dist/{handler-r-HYO3Oy.js → handler-3gksYOQv.js} +299 -99
- package/dist/{handler-r-HYO3Oy.js.map → handler-3gksYOQv.js.map} +1 -1
- package/dist/{handler-BNrqh1Kb.js → handler-BsauvgjA.js} +58 -19
- package/dist/{handler-BNrqh1Kb.js.map → handler-BsauvgjA.js.map} +1 -1
- package/dist/{handler-Cohj3cz3.js → handler-DY5UEwlw.js} +45 -18
- package/dist/{handler-Cohj3cz3.js.map → handler-DY5UEwlw.js.map} +1 -1
- package/dist/{handler-Bh3a6Br1.js → handler-GZgk5k3c.js} +326 -130
- package/dist/{handler-Bh3a6Br1.js.map → handler-GZgk5k3c.js.map} +1 -1
- package/dist/index.js +293 -155
- package/dist/index.js.map +1 -1
- package/dist/notifications.js +103 -32
- package/dist/notifications.js.map +1 -1
- package/dist/{queryExecutor-DSCpsVI8.js → queryExecutor-Dn62mIDL.js} +47 -33
- package/dist/{queryExecutor-DSCpsVI8.js.map → queryExecutor-Dn62mIDL.js.map} +1 -1
- package/dist/rts/index.js +99 -21
- package/dist/rts/index.js.map +1 -1
- package/dist/{shared-BJomDDWK.js → shared-Dy9x-P7F.js} +10 -7
- package/dist/{shared-BJomDDWK.js.map → shared-Dy9x-P7F.js.map} +1 -1
- package/dist/uploads.js +1 -1
- package/dist/uploads.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ import { dirname, posix, sep } from "path";
|
|
|
9
9
|
import fs, { createReadStream, readFileSync } from "node:fs";
|
|
10
10
|
import { createInterface } from "node:readline";
|
|
11
11
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
12
|
-
import { g as getDerivedKey, r as resolveRtsRequestTenantId, i as isRtsRequestAuthorized, b as buildRtsAbilityFromRequest, n as normalizeRtsQueryOptions, a as runRtsQuery } from "./queryExecutor-
|
|
12
|
+
import { g as getDerivedKey, r as resolveRtsRequestTenantId, i as isRtsRequestAuthorized, b as buildRtsAbilityFromRequest, n as normalizeRtsQueryOptions, a as runRtsQuery } from "./queryExecutor-Dn62mIDL.js";
|
|
13
13
|
import httpProxy from "http-proxy-3";
|
|
14
14
|
import fsPromises from "node:fs/promises";
|
|
15
15
|
import inspector from "node:inspector";
|
|
@@ -21,7 +21,7 @@ import { StrictMode, createElement } from "react";
|
|
|
21
21
|
import { renderToPipeableStream, renderToStaticMarkup } from "react-dom/server";
|
|
22
22
|
import { jsx } from "react/jsx-runtime";
|
|
23
23
|
import { createPath, matchRoutes, parsePath, createStaticRouter, StaticRouterProvider } from "@rpcbase/router";
|
|
24
|
-
import { s } from "./email-
|
|
24
|
+
import { s } from "./email-DK8uUU4X.js";
|
|
25
25
|
function getDefaultExportFromCjs(x) {
|
|
26
26
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
|
|
27
27
|
}
|
|
@@ -3491,7 +3491,9 @@ const metricsIngestProxyMiddleware = (app) => {
|
|
|
3491
3491
|
if (!req.url) {
|
|
3492
3492
|
req.url = "/";
|
|
3493
3493
|
}
|
|
3494
|
-
proxy.web(req, res, {
|
|
3494
|
+
proxy.web(req, res, {
|
|
3495
|
+
target: POSTHOG_INGEST_TARGET
|
|
3496
|
+
});
|
|
3495
3497
|
});
|
|
3496
3498
|
};
|
|
3497
3499
|
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
@@ -3509,7 +3511,9 @@ const checkInitReplicaSet = async (serverEnv) => {
|
|
|
3509
3511
|
const maxWaitAttempts = 10;
|
|
3510
3512
|
for (let attempt = 1; attempt <= maxWaitAttempts; attempt++) {
|
|
3511
3513
|
try {
|
|
3512
|
-
const status = await admin.command({
|
|
3514
|
+
const status = await admin.command({
|
|
3515
|
+
replSetGetStatus: 1
|
|
3516
|
+
});
|
|
3513
3517
|
const state = Number(status?.myState ?? 0);
|
|
3514
3518
|
if (status?.ok && (state === 1 || state === 2)) return;
|
|
3515
3519
|
} catch {
|
|
@@ -3527,9 +3531,13 @@ const checkInitReplicaSet = async (serverEnv) => {
|
|
|
3527
3531
|
});
|
|
3528
3532
|
await client2.connect();
|
|
3529
3533
|
const admin = client2.db("admin").admin();
|
|
3530
|
-
await admin.command({
|
|
3534
|
+
await admin.command({
|
|
3535
|
+
ping: 1
|
|
3536
|
+
});
|
|
3531
3537
|
try {
|
|
3532
|
-
await admin.command({
|
|
3538
|
+
await admin.command({
|
|
3539
|
+
replSetGetStatus: 1
|
|
3540
|
+
});
|
|
3533
3541
|
return;
|
|
3534
3542
|
} catch (error) {
|
|
3535
3543
|
const codeName = error?.codeName;
|
|
@@ -3538,7 +3546,10 @@ const checkInitReplicaSet = async (serverEnv) => {
|
|
|
3538
3546
|
const res = await admin.command({
|
|
3539
3547
|
replSetInitiate: {
|
|
3540
3548
|
_id: replSetName,
|
|
3541
|
-
members: [{
|
|
3549
|
+
members: [{
|
|
3550
|
+
_id: 0,
|
|
3551
|
+
host: memberHost
|
|
3552
|
+
}]
|
|
3542
3553
|
}
|
|
3543
3554
|
});
|
|
3544
3555
|
if (res?.ok) {
|
|
@@ -3552,9 +3563,7 @@ const checkInitReplicaSet = async (serverEnv) => {
|
|
|
3552
3563
|
const message2 = initError instanceof Error ? initError.message : String(initError);
|
|
3553
3564
|
console.warn(`[rb/server] MongoDB replica set initiation failed: ${message2}`);
|
|
3554
3565
|
if (initCodeName === "InvalidReplicaSetConfig") {
|
|
3555
|
-
console.warn(
|
|
3556
|
-
`[rb/server] Hint: the replica set member host must match the mongod address/port. If MongoDB runs in Docker with port mapping, ensure the container listens on ${port} (e.g. mongod --port ${port}) instead of the default 27017.`
|
|
3557
|
-
);
|
|
3566
|
+
console.warn(`[rb/server] Hint: the replica set member host must match the mongod address/port. If MongoDB runs in Docker with port mapping, ensure the container listens on ${port} (e.g. mongod --port ${port}) instead of the default 27017.`);
|
|
3558
3567
|
}
|
|
3559
3568
|
}
|
|
3560
3569
|
}
|
|
@@ -3564,9 +3573,7 @@ const checkInitReplicaSet = async (serverEnv) => {
|
|
|
3564
3573
|
if (codeName === "NoReplicationEnabled") {
|
|
3565
3574
|
if (!hasWarnedNoReplicationEnabled) {
|
|
3566
3575
|
hasWarnedNoReplicationEnabled = true;
|
|
3567
|
-
console.warn(
|
|
3568
|
-
`[rb/server] MongoDB is not started with --replSet ${replSetName} (replication disabled). Change streams require a replica set; start mongod with --replSet.`
|
|
3569
|
-
);
|
|
3576
|
+
console.warn(`[rb/server] MongoDB is not started with --replSet ${replSetName} (replication disabled). Change streams require a replica set; start mongod with --replSet.`);
|
|
3570
3577
|
}
|
|
3571
3578
|
return;
|
|
3572
3579
|
}
|
|
@@ -3628,10 +3635,7 @@ const findWorkspaceRoot = (projectRoot) => {
|
|
|
3628
3635
|
const stripQuery = (url) => {
|
|
3629
3636
|
const queryIndex = url.indexOf("?");
|
|
3630
3637
|
const hashIndex = url.indexOf("#");
|
|
3631
|
-
const endIndex = Math.min(
|
|
3632
|
-
queryIndex === -1 ? Number.POSITIVE_INFINITY : queryIndex,
|
|
3633
|
-
hashIndex === -1 ? Number.POSITIVE_INFINITY : hashIndex
|
|
3634
|
-
);
|
|
3638
|
+
const endIndex = Math.min(queryIndex === -1 ? Number.POSITIVE_INFINITY : queryIndex, hashIndex === -1 ? Number.POSITIVE_INFINITY : hashIndex);
|
|
3635
3639
|
if (!Number.isFinite(endIndex)) {
|
|
3636
3640
|
return url;
|
|
3637
3641
|
}
|
|
@@ -3703,7 +3707,9 @@ const normalizeScriptUrl = async (rawUrl, roots) => {
|
|
|
3703
3707
|
};
|
|
3704
3708
|
const fetchScriptSource = async (session2, scriptId) => {
|
|
3705
3709
|
try {
|
|
3706
|
-
const response = await post(session2, "Debugger.getScriptSource", {
|
|
3710
|
+
const response = await post(session2, "Debugger.getScriptSource", {
|
|
3711
|
+
scriptId
|
|
3712
|
+
});
|
|
3707
3713
|
return typeof response?.scriptSource === "string" ? response.scriptSource : "";
|
|
3708
3714
|
} catch {
|
|
3709
3715
|
return "";
|
|
@@ -3719,11 +3725,7 @@ const resolveScriptSource = async (session2, cache, scriptId) => {
|
|
|
3719
3725
|
return await promise;
|
|
3720
3726
|
};
|
|
3721
3727
|
const shutdownSession = async (session2) => {
|
|
3722
|
-
await Promise.allSettled([
|
|
3723
|
-
post(session2, "Profiler.stopPreciseCoverage").catch(() => void 0),
|
|
3724
|
-
post(session2, "Profiler.disable").catch(() => void 0),
|
|
3725
|
-
post(session2, "Debugger.disable").catch(() => void 0)
|
|
3726
|
-
]);
|
|
3728
|
+
await Promise.allSettled([post(session2, "Profiler.stopPreciseCoverage").catch(() => void 0), post(session2, "Profiler.disable").catch(() => void 0), post(session2, "Debugger.disable").catch(() => void 0)]);
|
|
3727
3729
|
try {
|
|
3728
3730
|
session2.disconnect();
|
|
3729
3731
|
} catch {
|
|
@@ -3762,11 +3764,17 @@ const classifyServerTarget = (absolutePath, projectRoot) => {
|
|
|
3762
3764
|
function registerDevCoverageEndpoints(app) {
|
|
3763
3765
|
app.post("/api/dev/coverage/start", async (_req, res) => {
|
|
3764
3766
|
if (process.env.NODE_ENV === "production") {
|
|
3765
|
-
res.status(404).json({
|
|
3767
|
+
res.status(404).json({
|
|
3768
|
+
error: "Not Found"
|
|
3769
|
+
});
|
|
3766
3770
|
return;
|
|
3767
3771
|
}
|
|
3768
3772
|
if (activeRun) {
|
|
3769
|
-
res.json({
|
|
3773
|
+
res.json({
|
|
3774
|
+
ok: true,
|
|
3775
|
+
status: "already_started",
|
|
3776
|
+
startedAt: activeRun.startedAt
|
|
3777
|
+
});
|
|
3770
3778
|
return;
|
|
3771
3779
|
}
|
|
3772
3780
|
const roots = {
|
|
@@ -3778,28 +3786,43 @@ function registerDevCoverageEndpoints(app) {
|
|
|
3778
3786
|
try {
|
|
3779
3787
|
await post(session2, "Debugger.enable");
|
|
3780
3788
|
await post(session2, "Profiler.enable");
|
|
3781
|
-
await post(session2, "Profiler.startPreciseCoverage", {
|
|
3789
|
+
await post(session2, "Profiler.startPreciseCoverage", {
|
|
3790
|
+
callCount: false,
|
|
3791
|
+
detailed: true
|
|
3792
|
+
});
|
|
3782
3793
|
activeRun = {
|
|
3783
3794
|
roots,
|
|
3784
3795
|
session: session2,
|
|
3785
3796
|
sourceCache: /* @__PURE__ */ new Map(),
|
|
3786
3797
|
startedAt: Date.now()
|
|
3787
3798
|
};
|
|
3788
|
-
res.json({
|
|
3799
|
+
res.json({
|
|
3800
|
+
ok: true,
|
|
3801
|
+
status: "started",
|
|
3802
|
+
startedAt: activeRun.startedAt
|
|
3803
|
+
});
|
|
3789
3804
|
} catch (error) {
|
|
3790
3805
|
await shutdownSession(session2);
|
|
3791
3806
|
activeRun = null;
|
|
3792
|
-
res.status(500).json({
|
|
3807
|
+
res.status(500).json({
|
|
3808
|
+
ok: false,
|
|
3809
|
+
error: describeError(error)
|
|
3810
|
+
});
|
|
3793
3811
|
}
|
|
3794
3812
|
});
|
|
3795
3813
|
app.post("/api/dev/coverage/stop", async (req, res) => {
|
|
3796
3814
|
if (process.env.NODE_ENV === "production") {
|
|
3797
|
-
res.status(404).json({
|
|
3815
|
+
res.status(404).json({
|
|
3816
|
+
error: "Not Found"
|
|
3817
|
+
});
|
|
3798
3818
|
return;
|
|
3799
3819
|
}
|
|
3800
3820
|
const run = activeRun;
|
|
3801
3821
|
if (!run) {
|
|
3802
|
-
res.status(409).json({
|
|
3822
|
+
res.status(409).json({
|
|
3823
|
+
ok: false,
|
|
3824
|
+
error: "coverage_not_started"
|
|
3825
|
+
});
|
|
3803
3826
|
return;
|
|
3804
3827
|
}
|
|
3805
3828
|
activeRun = null;
|
|
@@ -3838,17 +3861,17 @@ function registerDevCoverageEndpoints(app) {
|
|
|
3838
3861
|
const target = classifyServerTarget(script.absolutePath, run.roots.projectRoot);
|
|
3839
3862
|
scriptsByTarget[target].push(script);
|
|
3840
3863
|
}
|
|
3841
|
-
await Promise.all(
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
);
|
|
3864
|
+
await Promise.all(Object.keys(outputFiles).map(async (target) => {
|
|
3865
|
+
const outputFile = outputFiles[target];
|
|
3866
|
+
const payload = {
|
|
3867
|
+
testId: `node-${target}`,
|
|
3868
|
+
scripts: scriptsByTarget[target]
|
|
3869
|
+
};
|
|
3870
|
+
await fsPromises.mkdir(path.dirname(outputFile), {
|
|
3871
|
+
recursive: true
|
|
3872
|
+
});
|
|
3873
|
+
await fsPromises.writeFile(outputFile, JSON.stringify(payload, null, 2), "utf8");
|
|
3874
|
+
}));
|
|
3852
3875
|
res.json({
|
|
3853
3876
|
ok: true,
|
|
3854
3877
|
status: "stopped",
|
|
@@ -3860,7 +3883,10 @@ function registerDevCoverageEndpoints(app) {
|
|
|
3860
3883
|
}
|
|
3861
3884
|
});
|
|
3862
3885
|
} catch (error) {
|
|
3863
|
-
res.status(500).json({
|
|
3886
|
+
res.status(500).json({
|
|
3887
|
+
ok: false,
|
|
3888
|
+
error: describeError(error)
|
|
3889
|
+
});
|
|
3864
3890
|
} finally {
|
|
3865
3891
|
await shutdownSession(run.session);
|
|
3866
3892
|
}
|
|
@@ -3939,7 +3965,9 @@ const createRedisSessionStore = async (redisUrl) => {
|
|
|
3939
3965
|
});
|
|
3940
3966
|
};
|
|
3941
3967
|
const initServer = async (app, serverEnv) => {
|
|
3942
|
-
await initApiClient({
|
|
3968
|
+
await initApiClient({
|
|
3969
|
+
app
|
|
3970
|
+
});
|
|
3943
3971
|
const replicaSetInitPromise = checkInitReplicaSet(serverEnv).catch((error) => {
|
|
3944
3972
|
const message = error instanceof Error ? error.message : String(error);
|
|
3945
3973
|
console.warn(`[rb/server] MongoDB replica set auto-init error: ${message}`);
|
|
@@ -4038,34 +4066,72 @@ const parseEnvInt = (value) => {
|
|
|
4038
4066
|
return parsed;
|
|
4039
4067
|
};
|
|
4040
4068
|
const isPowerOfTwo = (value) => (value & value - 1) === 0;
|
|
4041
|
-
const estimateScryptMemoryBytes = ({
|
|
4069
|
+
const estimateScryptMemoryBytes = ({
|
|
4070
|
+
N,
|
|
4071
|
+
r,
|
|
4072
|
+
p
|
|
4073
|
+
}) => {
|
|
4042
4074
|
return 128 * r * (N + p);
|
|
4043
4075
|
};
|
|
4044
4076
|
const validateScryptParams = (params) => {
|
|
4045
|
-
const {
|
|
4077
|
+
const {
|
|
4078
|
+
N,
|
|
4079
|
+
r,
|
|
4080
|
+
p,
|
|
4081
|
+
keylen,
|
|
4082
|
+
saltBytes,
|
|
4083
|
+
maxmemBytes
|
|
4084
|
+
} = params;
|
|
4046
4085
|
if (!Number.isSafeInteger(N) || N < 2 || N > MAX_SCRYPT_N || !isPowerOfTwo(N)) {
|
|
4047
|
-
return {
|
|
4086
|
+
return {
|
|
4087
|
+
ok: false,
|
|
4088
|
+
error: "invalid_scrypt_N"
|
|
4089
|
+
};
|
|
4048
4090
|
}
|
|
4049
4091
|
if (!Number.isSafeInteger(r) || r < 1 || r > MAX_SCRYPT_R) {
|
|
4050
|
-
return {
|
|
4092
|
+
return {
|
|
4093
|
+
ok: false,
|
|
4094
|
+
error: "invalid_scrypt_r"
|
|
4095
|
+
};
|
|
4051
4096
|
}
|
|
4052
4097
|
if (!Number.isSafeInteger(p) || p < 1 || p > MAX_SCRYPT_P) {
|
|
4053
|
-
return {
|
|
4098
|
+
return {
|
|
4099
|
+
ok: false,
|
|
4100
|
+
error: "invalid_scrypt_p"
|
|
4101
|
+
};
|
|
4054
4102
|
}
|
|
4055
4103
|
if (!Number.isSafeInteger(keylen) || keylen < 16 || keylen > MAX_SCRYPT_KEYLEN) {
|
|
4056
|
-
return {
|
|
4104
|
+
return {
|
|
4105
|
+
ok: false,
|
|
4106
|
+
error: "invalid_scrypt_keylen"
|
|
4107
|
+
};
|
|
4057
4108
|
}
|
|
4058
4109
|
if (!Number.isSafeInteger(saltBytes) || saltBytes < 8 || saltBytes > MAX_SCRYPT_SALT_BYTES) {
|
|
4059
|
-
return {
|
|
4110
|
+
return {
|
|
4111
|
+
ok: false,
|
|
4112
|
+
error: "invalid_scrypt_salt_bytes"
|
|
4113
|
+
};
|
|
4060
4114
|
}
|
|
4061
4115
|
if (!Number.isSafeInteger(maxmemBytes) || maxmemBytes < 16 * 1024 * 1024 || maxmemBytes > MAX_SCRYPT_MAXMEM_BYTES) {
|
|
4062
|
-
return {
|
|
4116
|
+
return {
|
|
4117
|
+
ok: false,
|
|
4118
|
+
error: "invalid_scrypt_maxmem"
|
|
4119
|
+
};
|
|
4063
4120
|
}
|
|
4064
|
-
const estimatedMem = estimateScryptMemoryBytes({
|
|
4121
|
+
const estimatedMem = estimateScryptMemoryBytes({
|
|
4122
|
+
N,
|
|
4123
|
+
r,
|
|
4124
|
+
p
|
|
4125
|
+
});
|
|
4065
4126
|
if (estimatedMem > maxmemBytes) {
|
|
4066
|
-
return {
|
|
4127
|
+
return {
|
|
4128
|
+
ok: false,
|
|
4129
|
+
error: "scrypt_params_exceed_maxmem"
|
|
4130
|
+
};
|
|
4067
4131
|
}
|
|
4068
|
-
return {
|
|
4132
|
+
return {
|
|
4133
|
+
ok: true
|
|
4134
|
+
};
|
|
4069
4135
|
};
|
|
4070
4136
|
const getCurrentMaxmemBytes = (opts) => {
|
|
4071
4137
|
const envMaxmemBytes = parseEnvInt(process.env.RB_PASSWORD_SCRYPT_MAXMEM_BYTES);
|
|
@@ -4096,9 +4162,20 @@ const getCurrentScryptParams = (opts) => {
|
|
|
4096
4162
|
return params;
|
|
4097
4163
|
};
|
|
4098
4164
|
const scryptAsync = async (password, salt, params) => {
|
|
4099
|
-
const {
|
|
4165
|
+
const {
|
|
4166
|
+
N,
|
|
4167
|
+
r,
|
|
4168
|
+
p,
|
|
4169
|
+
keylen,
|
|
4170
|
+
maxmemBytes
|
|
4171
|
+
} = params;
|
|
4100
4172
|
return await new Promise((resolve, reject) => {
|
|
4101
|
-
crypto.scrypt(password, salt, keylen, {
|
|
4173
|
+
crypto.scrypt(password, salt, keylen, {
|
|
4174
|
+
N,
|
|
4175
|
+
r,
|
|
4176
|
+
p,
|
|
4177
|
+
maxmem: maxmemBytes
|
|
4178
|
+
}, (err, derivedKey) => {
|
|
4102
4179
|
if (err) {
|
|
4103
4180
|
reject(err);
|
|
4104
4181
|
return;
|
|
@@ -4166,12 +4243,32 @@ const parseStoredScryptHash = (stored) => {
|
|
|
4166
4243
|
maxmemBytes: currentMaxmemBytes
|
|
4167
4244
|
});
|
|
4168
4245
|
if (!validated.ok) return null;
|
|
4169
|
-
return {
|
|
4246
|
+
return {
|
|
4247
|
+
N,
|
|
4248
|
+
r,
|
|
4249
|
+
p,
|
|
4250
|
+
keylen,
|
|
4251
|
+
salt,
|
|
4252
|
+
dk
|
|
4253
|
+
};
|
|
4170
4254
|
};
|
|
4171
4255
|
async function hashPasswordForStorage(password, opts) {
|
|
4172
|
-
const {
|
|
4256
|
+
const {
|
|
4257
|
+
N,
|
|
4258
|
+
r,
|
|
4259
|
+
p,
|
|
4260
|
+
keylen,
|
|
4261
|
+
saltBytes,
|
|
4262
|
+
maxmemBytes
|
|
4263
|
+
} = getCurrentScryptParams(opts);
|
|
4173
4264
|
const salt = crypto.randomBytes(saltBytes);
|
|
4174
|
-
const dk = await scryptAsync(password, salt, {
|
|
4265
|
+
const dk = await scryptAsync(password, salt, {
|
|
4266
|
+
N,
|
|
4267
|
+
r,
|
|
4268
|
+
p,
|
|
4269
|
+
keylen,
|
|
4270
|
+
maxmemBytes
|
|
4271
|
+
});
|
|
4175
4272
|
const saltB64 = salt.toString("base64");
|
|
4176
4273
|
const dkB64 = dk.toString("base64");
|
|
4177
4274
|
return `$scrypt$N=${N},r=${r},p=${p},keylen=${keylen}$${saltB64}$${dkB64}`;
|
|
@@ -4179,11 +4276,24 @@ async function hashPasswordForStorage(password, opts) {
|
|
|
4179
4276
|
async function verifyPasswordFromStorage(password, stored) {
|
|
4180
4277
|
const parsed = parseStoredScryptHash(stored);
|
|
4181
4278
|
if (!parsed) return false;
|
|
4182
|
-
const {
|
|
4279
|
+
const {
|
|
4280
|
+
N,
|
|
4281
|
+
r,
|
|
4282
|
+
p,
|
|
4283
|
+
keylen,
|
|
4284
|
+
salt,
|
|
4285
|
+
dk
|
|
4286
|
+
} = parsed;
|
|
4183
4287
|
const maxmemBytes = getCurrentMaxmemBytes();
|
|
4184
4288
|
let derivedKey;
|
|
4185
4289
|
try {
|
|
4186
|
-
derivedKey = await scryptAsync(password, salt, {
|
|
4290
|
+
derivedKey = await scryptAsync(password, salt, {
|
|
4291
|
+
N,
|
|
4292
|
+
r,
|
|
4293
|
+
p,
|
|
4294
|
+
keylen,
|
|
4295
|
+
maxmemBytes
|
|
4296
|
+
});
|
|
4187
4297
|
} catch {
|
|
4188
4298
|
return false;
|
|
4189
4299
|
}
|
|
@@ -4210,14 +4320,12 @@ function getShortCircuitMatches(routes) {
|
|
|
4210
4320
|
id: "__shim-error-route__"
|
|
4211
4321
|
};
|
|
4212
4322
|
return {
|
|
4213
|
-
matches: [
|
|
4214
|
-
{
|
|
4215
|
-
|
|
4216
|
-
|
|
4217
|
-
|
|
4218
|
-
|
|
4219
|
-
}
|
|
4220
|
-
],
|
|
4323
|
+
matches: [{
|
|
4324
|
+
params: {},
|
|
4325
|
+
pathname: "",
|
|
4326
|
+
pathnameBase: "",
|
|
4327
|
+
route
|
|
4328
|
+
}],
|
|
4221
4329
|
route
|
|
4222
4330
|
};
|
|
4223
4331
|
}
|
|
@@ -4232,9 +4340,7 @@ const getErrorStatus = (error) => {
|
|
|
4232
4340
|
return void 0;
|
|
4233
4341
|
};
|
|
4234
4342
|
const isResponseLike = (value) => {
|
|
4235
|
-
return Boolean(
|
|
4236
|
-
value && typeof value === "object" && typeof value.status === "number" && value.headers && typeof value.headers.get === "function"
|
|
4237
|
-
);
|
|
4343
|
+
return Boolean(value && typeof value === "object" && typeof value.status === "number" && value.headers && typeof value.headers.get === "function");
|
|
4238
4344
|
};
|
|
4239
4345
|
const isRedirectResponse = (value) => {
|
|
4240
4346
|
if (!isResponseLike(value)) return false;
|
|
@@ -4273,13 +4379,18 @@ async function applyRouteLoaders(req, dataRoutes) {
|
|
|
4273
4379
|
status: 404,
|
|
4274
4380
|
message: `No route matches URL: ${req.originalUrl}`
|
|
4275
4381
|
};
|
|
4276
|
-
const {
|
|
4382
|
+
const {
|
|
4383
|
+
matches: notFoundMatches,
|
|
4384
|
+
route
|
|
4385
|
+
} = getShortCircuitMatches(dataRoutes);
|
|
4277
4386
|
return {
|
|
4278
4387
|
...baseContext,
|
|
4279
4388
|
matches: notFoundMatches,
|
|
4280
4389
|
loaderData: {},
|
|
4281
4390
|
actionData: null,
|
|
4282
|
-
errors: {
|
|
4391
|
+
errors: {
|
|
4392
|
+
[route.id]: error
|
|
4393
|
+
},
|
|
4283
4394
|
statusCode: 404
|
|
4284
4395
|
};
|
|
4285
4396
|
}
|
|
@@ -4305,18 +4416,32 @@ async function applyRouteLoaders(req, dataRoutes) {
|
|
|
4305
4416
|
ms: LOADER_TIMEOUT_MS,
|
|
4306
4417
|
url: req.originalUrl
|
|
4307
4418
|
});
|
|
4308
|
-
reject({
|
|
4419
|
+
reject({
|
|
4420
|
+
id: route.id,
|
|
4421
|
+
path: route.path,
|
|
4422
|
+
reason: err
|
|
4423
|
+
});
|
|
4309
4424
|
}, LOADER_TIMEOUT_MS);
|
|
4310
4425
|
});
|
|
4311
4426
|
const loaderPromise = (async () => {
|
|
4312
4427
|
try {
|
|
4313
4428
|
const data = await route.loader({
|
|
4314
4429
|
params,
|
|
4315
|
-
ctx: {
|
|
4430
|
+
ctx: {
|
|
4431
|
+
req
|
|
4432
|
+
}
|
|
4316
4433
|
});
|
|
4317
|
-
return {
|
|
4434
|
+
return {
|
|
4435
|
+
id: route.id,
|
|
4436
|
+
path: route.path,
|
|
4437
|
+
data
|
|
4438
|
+
};
|
|
4318
4439
|
} catch (error) {
|
|
4319
|
-
throw {
|
|
4440
|
+
throw {
|
|
4441
|
+
id: route.id,
|
|
4442
|
+
path: route.path,
|
|
4443
|
+
reason: error
|
|
4444
|
+
};
|
|
4320
4445
|
} finally {
|
|
4321
4446
|
if (timeoutId) {
|
|
4322
4447
|
clearTimeout(timeoutId);
|
|
@@ -4325,9 +4450,7 @@ async function applyRouteLoaders(req, dataRoutes) {
|
|
|
4325
4450
|
})();
|
|
4326
4451
|
return Promise.race([loaderPromise, timeoutPromise]);
|
|
4327
4452
|
};
|
|
4328
|
-
const loaderPromisesResults = await Promise.allSettled(
|
|
4329
|
-
matches.map((match) => runLoaderWithTimeout(match.route, match.params))
|
|
4330
|
-
);
|
|
4453
|
+
const loaderPromisesResults = await Promise.allSettled(matches.map((match) => runLoaderWithTimeout(match.route, match.params)));
|
|
4331
4454
|
const loaderData = {};
|
|
4332
4455
|
let errors = null;
|
|
4333
4456
|
let hasNotFoundError = false;
|
|
@@ -4349,9 +4472,7 @@ async function applyRouteLoaders(req, dataRoutes) {
|
|
|
4349
4472
|
} else if (result.status === "rejected") {
|
|
4350
4473
|
const id = result.reason?.id;
|
|
4351
4474
|
if (!id) {
|
|
4352
|
-
throw new Error(
|
|
4353
|
-
`missing route ID in error: ${result.reason}`
|
|
4354
|
-
);
|
|
4475
|
+
throw new Error(`missing route ID in error: ${result.reason}`);
|
|
4355
4476
|
}
|
|
4356
4477
|
const reasonCandidate = result.reason?.reason ?? result.reason;
|
|
4357
4478
|
if (isRedirectResponse(reasonCandidate)) {
|
|
@@ -4460,7 +4581,10 @@ const createRtsSsrCollector = (req, opts) => {
|
|
|
4460
4581
|
if (hasSessionUser(req) && !isRtsRequestAuthorized(req, tenantId)) {
|
|
4461
4582
|
return null;
|
|
4462
4583
|
}
|
|
4463
|
-
const {
|
|
4584
|
+
const {
|
|
4585
|
+
ability,
|
|
4586
|
+
userId
|
|
4587
|
+
} = await buildRtsAbilityFromRequest(req, tenantId);
|
|
4464
4588
|
const queryEntries = [];
|
|
4465
4589
|
for (const registration of registrations.values()) {
|
|
4466
4590
|
const options = normalizeRtsQueryOptions(registration.options);
|
|
@@ -4477,7 +4601,9 @@ const createRtsSsrCollector = (req, opts) => {
|
|
|
4477
4601
|
modelName: registration.modelName,
|
|
4478
4602
|
queryKey: registration.queryKey,
|
|
4479
4603
|
data: boundedData,
|
|
4480
|
-
...result.pageInfo ? {
|
|
4604
|
+
...result.pageInfo ? {
|
|
4605
|
+
pageInfo: result.pageInfo
|
|
4606
|
+
} : {}
|
|
4481
4607
|
});
|
|
4482
4608
|
} catch {
|
|
4483
4609
|
continue;
|
|
@@ -4507,7 +4633,11 @@ const createRtsSsrCollector = (req, opts) => {
|
|
|
4507
4633
|
return payload.queries.length ? payload : null;
|
|
4508
4634
|
};
|
|
4509
4635
|
const hasRegistrations = () => registrations.size > 0;
|
|
4510
|
-
return {
|
|
4636
|
+
return {
|
|
4637
|
+
runtime,
|
|
4638
|
+
hasRegistrations,
|
|
4639
|
+
resolve
|
|
4640
|
+
};
|
|
4511
4641
|
};
|
|
4512
4642
|
const renderRtsHydrationScript = (data) => {
|
|
4513
4643
|
if (!data) return "";
|
|
@@ -4538,7 +4668,10 @@ const runRtsPrepass = async (element) => {
|
|
|
4538
4668
|
sink.on("error", () => {
|
|
4539
4669
|
finish(false);
|
|
4540
4670
|
});
|
|
4541
|
-
const {
|
|
4671
|
+
const {
|
|
4672
|
+
pipe,
|
|
4673
|
+
abort
|
|
4674
|
+
} = renderToPipeableStream(element, {
|
|
4542
4675
|
onAllReady() {
|
|
4543
4676
|
if (isDone) return;
|
|
4544
4677
|
pipe(sink);
|
|
@@ -4582,13 +4715,10 @@ async function renderSSR(req, dataRoutes) {
|
|
|
4582
4715
|
pathname: m.pathname,
|
|
4583
4716
|
pathnameBase: m.pathnameBase
|
|
4584
4717
|
}));
|
|
4585
|
-
console.error(
|
|
4586
|
-
|
|
4587
|
-
|
|
4588
|
-
|
|
4589
|
-
matches: matchesSummary
|
|
4590
|
-
}
|
|
4591
|
-
);
|
|
4718
|
+
console.error(`SSR ${routerContext.statusCode || 500} ${req.method} ${req.originalUrl}`, {
|
|
4719
|
+
errors: routerContext.errors,
|
|
4720
|
+
matches: matchesSummary
|
|
4721
|
+
});
|
|
4592
4722
|
const errorEntries = Object.entries(routerContext.errors || {});
|
|
4593
4723
|
const firstErrorEntry = errorEntries[0]?.[1];
|
|
4594
4724
|
const firstReason = firstErrorEntry?.reason ?? firstErrorEntry;
|
|
@@ -4695,7 +4825,9 @@ const sendErrorResponse = ({
|
|
|
4695
4825
|
const start = htmlStart ?? FALLBACK_ERROR_TEMPLATE_START;
|
|
4696
4826
|
const end = htmlEnd ?? FALLBACK_ERROR_TEMPLATE_END;
|
|
4697
4827
|
res.status(status);
|
|
4698
|
-
res.set({
|
|
4828
|
+
res.set({
|
|
4829
|
+
"Content-Type": "text/html"
|
|
4830
|
+
});
|
|
4699
4831
|
const details = formatErrorDetails(error);
|
|
4700
4832
|
const state = {
|
|
4701
4833
|
statusCode: status,
|
|
@@ -4703,16 +4835,12 @@ const sendErrorResponse = ({
|
|
|
4703
4835
|
message,
|
|
4704
4836
|
details
|
|
4705
4837
|
};
|
|
4706
|
-
const markup = renderToStaticMarkup(
|
|
4707
|
-
|
|
4708
|
-
|
|
4709
|
-
|
|
4710
|
-
|
|
4711
|
-
|
|
4712
|
-
renderErrorExtra: errorExtraComponent ? (payload) => createElement(errorExtraComponent, { state: payload }) : void 0
|
|
4713
|
-
})
|
|
4714
|
-
)
|
|
4715
|
-
);
|
|
4838
|
+
const markup = renderToStaticMarkup(createElement(StrictMode, null, createElement(SsrErrorFallback, {
|
|
4839
|
+
state,
|
|
4840
|
+
renderErrorExtra: errorExtraComponent ? (payload) => createElement(errorExtraComponent, {
|
|
4841
|
+
state: payload
|
|
4842
|
+
}) : void 0
|
|
4843
|
+
})));
|
|
4716
4844
|
const serializedState = `<script>window.${SSR_ERROR_STATE_GLOBAL_KEY}=${serializeSsrErrorState({
|
|
4717
4845
|
...state,
|
|
4718
4846
|
details: isProduction ? void 0 : details
|
|
@@ -4753,7 +4881,9 @@ const ssrMiddleware = ({
|
|
|
4753
4881
|
});
|
|
4754
4882
|
responseCommitted = true;
|
|
4755
4883
|
if (error) {
|
|
4756
|
-
captureException(error, {
|
|
4884
|
+
captureException(error, {
|
|
4885
|
+
phase: "finalizeWithErrorPage"
|
|
4886
|
+
});
|
|
4757
4887
|
}
|
|
4758
4888
|
};
|
|
4759
4889
|
try {
|
|
@@ -4808,55 +4938,61 @@ const ssrMiddleware = ({
|
|
|
4808
4938
|
return;
|
|
4809
4939
|
}
|
|
4810
4940
|
let didError = false;
|
|
4811
|
-
const {
|
|
4812
|
-
|
|
4813
|
-
|
|
4814
|
-
|
|
4815
|
-
|
|
4816
|
-
|
|
4817
|
-
|
|
4818
|
-
|
|
4819
|
-
|
|
4820
|
-
|
|
4821
|
-
|
|
4822
|
-
}
|
|
4823
|
-
|
|
4824
|
-
|
|
4825
|
-
|
|
4826
|
-
|
|
4827
|
-
|
|
4828
|
-
|
|
4829
|
-
|
|
4830
|
-
}
|
|
4831
|
-
|
|
4832
|
-
|
|
4833
|
-
|
|
4834
|
-
|
|
4835
|
-
|
|
4836
|
-
|
|
4837
|
-
|
|
4838
|
-
|
|
4839
|
-
|
|
4840
|
-
|
|
4841
|
-
|
|
4842
|
-
|
|
4843
|
-
const transformStream = new Transform({
|
|
4844
|
-
transform(chunk, encoding, callback) {
|
|
4845
|
-
res.write(chunk, encoding);
|
|
4846
|
-
callback();
|
|
4847
|
-
}
|
|
4848
|
-
});
|
|
4849
|
-
const start = htmlStart;
|
|
4850
|
-
const end = htmlEnd;
|
|
4851
|
-
const rtsHydrationScript = renderRtsHydrationScript(rtsHydrationData);
|
|
4852
|
-
res.write(start);
|
|
4853
|
-
transformStream.on("finish", () => {
|
|
4854
|
-
res.end(`${rtsHydrationScript}${end}`);
|
|
4855
|
-
});
|
|
4856
|
-
pipe(transformStream);
|
|
4941
|
+
const {
|
|
4942
|
+
pipe,
|
|
4943
|
+
abort
|
|
4944
|
+
} = renderToPipeableStream(element, {
|
|
4945
|
+
onShellError(error) {
|
|
4946
|
+
if (error instanceof Error) {
|
|
4947
|
+
viteInstance?.ssrFixStacktrace(error);
|
|
4948
|
+
}
|
|
4949
|
+
console.error("SSR shell error", error);
|
|
4950
|
+
captureException(error, {
|
|
4951
|
+
phase: "shell"
|
|
4952
|
+
});
|
|
4953
|
+
finalizeWithErrorPage(error);
|
|
4954
|
+
abort();
|
|
4955
|
+
},
|
|
4956
|
+
onError(error) {
|
|
4957
|
+
didError = true;
|
|
4958
|
+
if (error instanceof Error) {
|
|
4959
|
+
viteInstance?.ssrFixStacktrace(error);
|
|
4960
|
+
}
|
|
4961
|
+
console.error("SSR rendering error", error);
|
|
4962
|
+
captureException(error, {
|
|
4963
|
+
phase: "render"
|
|
4964
|
+
});
|
|
4965
|
+
},
|
|
4966
|
+
onShellReady() {
|
|
4967
|
+
if (responseCommitted) {
|
|
4968
|
+
return;
|
|
4969
|
+
}
|
|
4970
|
+
if (!htmlStart || !htmlEnd) {
|
|
4971
|
+
finalizeWithErrorPage();
|
|
4972
|
+
return;
|
|
4857
4973
|
}
|
|
4974
|
+
responseCommitted = true;
|
|
4975
|
+
const responseStatus = didError ? 500 : statusCode || 200;
|
|
4976
|
+
res.status(responseStatus);
|
|
4977
|
+
res.set({
|
|
4978
|
+
"Content-Type": "text/html"
|
|
4979
|
+
});
|
|
4980
|
+
const transformStream = new Transform({
|
|
4981
|
+
transform(chunk, encoding, callback) {
|
|
4982
|
+
res.write(chunk, encoding);
|
|
4983
|
+
callback();
|
|
4984
|
+
}
|
|
4985
|
+
});
|
|
4986
|
+
const start = htmlStart;
|
|
4987
|
+
const end = htmlEnd;
|
|
4988
|
+
const rtsHydrationScript = renderRtsHydrationScript(rtsHydrationData);
|
|
4989
|
+
res.write(start);
|
|
4990
|
+
transformStream.on("finish", () => {
|
|
4991
|
+
res.end(`${rtsHydrationScript}${end}`);
|
|
4992
|
+
});
|
|
4993
|
+
pipe(transformStream);
|
|
4858
4994
|
}
|
|
4859
|
-
);
|
|
4995
|
+
});
|
|
4860
4996
|
setTimeout(() => {
|
|
4861
4997
|
abort();
|
|
4862
4998
|
}, ABORT_DELAY_MS);
|
|
@@ -4868,7 +5004,9 @@ const ssrMiddleware = ({
|
|
|
4868
5004
|
} else {
|
|
4869
5005
|
console.error("Unknown SSR middleware error", err);
|
|
4870
5006
|
}
|
|
4871
|
-
captureException(err, {
|
|
5007
|
+
captureException(err, {
|
|
5008
|
+
phase: "catch"
|
|
5009
|
+
});
|
|
4872
5010
|
finalizeWithErrorPage(err);
|
|
4873
5011
|
}
|
|
4874
5012
|
};
|