@luckystack/core 0.13.0 → 0.15.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/CHANGELOG.md +40 -0
- package/dist/bootUuid.d.ts +16 -0
- package/dist/{chunk-PN2FPJXI.js → chunk-55YXIACQ.js} +1 -1
- package/dist/chunk-55YXIACQ.js.map +1 -0
- package/dist/{chunk-RC7ZQBO6.js → chunk-EZIBIQXO.js} +3 -3
- package/dist/{chunk-C4AK6P5D.js → chunk-NJULJZ3N.js} +29 -17
- package/dist/chunk-NJULJZ3N.js.map +1 -0
- package/dist/{chunk-6UPWMV6L.js → chunk-YKVBUWB6.js} +2 -2
- package/dist/chunk-YKVBUWB6.js.map +1 -0
- package/dist/client.d.ts +1 -1
- package/dist/client.js +74 -12
- package/dist/client.js.map +1 -1
- package/dist/config.js +2 -2
- package/dist/deployConfigRegistry.d.ts +3 -1
- package/dist/emailRegistry.d.ts +12 -1
- package/dist/errorTrackerIdentity.d.ts +2 -0
- package/dist/hooks/registry.d.ts +8 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +142 -32
- package/dist/index.js.map +1 -1
- package/dist/localSocketEnumerationGuard.d.ts +2 -1
- package/dist/middlewareRegistry.d.ts +13 -1
- package/dist/{projectConfig-EOJRMH36.js → projectConfig-6QNMG5GZ.js} +2 -2
- package/dist/projectConfig.d.ts +13 -9
- package/dist/react/languageOverride.d.ts +8 -0
- package/dist/redactedLogKeys.d.ts +2 -0
- package/dist/roomNameFormatterRegistry.d.ts +7 -5
- package/dist/{sentrySetup-T7535RYZ.js → sentrySetup-MZTUOMHL.js} +3 -3
- package/dist/sessionProviderRegistry.d.ts +14 -6
- package/package.json +1 -1
- package/dist/chunk-6UPWMV6L.js.map +0 -1
- package/dist/chunk-C4AK6P5D.js.map +0 -1
- package/dist/chunk-PN2FPJXI.js.map +0 -1
- /package/dist/{chunk-RC7ZQBO6.js.map → chunk-EZIBIQXO.js.map} +0 -0
- /package/dist/{projectConfig-EOJRMH36.js.map → projectConfig-6QNMG5GZ.js.map} +0 -0
- /package/dist/{sentrySetup-T7535RYZ.js.map → sentrySetup-MZTUOMHL.js.map} +0 -0
package/dist/hooks/registry.d.ts
CHANGED
|
@@ -6,7 +6,14 @@ export type DispatchResult = {
|
|
|
6
6
|
signal: HookStopSignal;
|
|
7
7
|
};
|
|
8
8
|
export declare const registerHook: <TName extends HookName>(name: TName, handler: HookHandler<HookPayloads[TName]>) => (() => void);
|
|
9
|
-
export
|
|
9
|
+
export interface DispatchHookOptions {
|
|
10
|
+
/**
|
|
11
|
+
* Receives a throwing handler's error instead of the default log line and
|
|
12
|
+
* tracker capture, e.g. to redact it or to report many dispatches at once.
|
|
13
|
+
*/
|
|
14
|
+
onError?: (error: unknown) => void;
|
|
15
|
+
}
|
|
16
|
+
export declare const dispatchHook: <TName extends HookName>(name: TName, payload: HookPayloads[TName], options?: DispatchHookOptions) => Promise<DispatchResult>;
|
|
10
17
|
export declare const clearAllHooks: () => void;
|
|
11
18
|
export declare const registerSyncHook: <TName extends SyncHookName>(name: TName, handler: SyncHookHandler<SyncHookPayloads[TName]>) => (() => void);
|
|
12
19
|
export declare const dispatchSyncHook: <TName extends SyncHookName>(name: TName, payload: SyncHookPayloads[TName]) => void;
|
package/dist/index.d.ts
CHANGED
|
@@ -49,7 +49,7 @@ export type { BaseSessionLayout, SessionLocation, AuthProps, Jsonify } from './s
|
|
|
49
49
|
export * from './sentrySetup.js';
|
|
50
50
|
export { registerErrorTracker, registerErrorTrackers, appendErrorTracker, getActiveErrorTrackers, captureExceptionAcrossTrackers, captureMessageAcrossTrackers, setErrorTrackerUser, recordMetricAcrossTrackers, startSpanAcrossTrackers, startSpanHandle, registerPreCaptureFilter, flushErrorTrackers, sanitizeErrorString, sanitizeErrorStrings, } from './errorTrackerRegistry.js';
|
|
51
51
|
export type { ErrorTracker, ErrorTrackerContext, ErrorTrackerUser, ErrorTrackerEvent, SpanResult, SpanHandle, PreCaptureFilter, } from './errorTrackerRegistry.js';
|
|
52
|
-
export { runWithErrorTrackerIdentity, runWithErrorTrackerIdentityScope, setCurrentErrorTrackerIdentity, getCurrentErrorTrackerIdentity, } from './errorTrackerIdentity.js';
|
|
52
|
+
export { runWithErrorTrackerIdentity, runWithErrorTrackerIdentityScope, setCurrentErrorTrackerIdentity, getCurrentErrorTrackerIdentity, hasErrorTrackerIdentityScope, } from './errorTrackerIdentity.js';
|
|
53
53
|
export * from './env.js';
|
|
54
54
|
export * from './db.js';
|
|
55
55
|
export { registerDbHealthCheck, getDbHealthCheck, isDbHealthCheckRegistered, resetDbHealthCheckForTests, } from './dbHealthCheck.js';
|
|
@@ -63,7 +63,7 @@ export type { RedisKeyFormatter } from './redisKeyFormatter.js';
|
|
|
63
63
|
export { acquireLease, renewLease, releaseLease } from './lease.js';
|
|
64
64
|
export { DEFAULT_CLIENT_KEY, registerPrismaClient, registerRedisClient, getPrismaClient, getRedisClient, getPrismaClientFor, getRedisClientFor, getPrismaClientKeys, getRedisClientKeys, isPrismaClientRegistered, isRedisClientRegistered, resetClientsForTests, } from './clients.js';
|
|
65
65
|
export { attachSocketRedisAdapter, resolveSocketAdapterKey } from './socketRedisAdapter.js';
|
|
66
|
-
export { writeBootUuid, readBootUuid, refreshBootUuid, startBootUuidHeartbeat, resolveEnvKey, BOOT_KEY_PREFIX, type BootUuidHeartbeat, } from './bootUuid.js';
|
|
66
|
+
export { writeBootUuid, readBootUuid, refreshBootUuid, startBootUuidHeartbeat, resolveEnvKey, BOOT_KEY_PREFIX, bootUuidKey, type BootUuidHeartbeat, } from './bootUuid.js';
|
|
67
67
|
export { collectSynchronizedEnvKeys, computeSynchronizedEnvHashes, hashSynchronizedValue, hashSynchronizedValueWith, resolveHealthHashConfig, describeHealthHashConfig, resolveHealthHashConfigFromDescriptor, } from './synchronizedEnvHashes.js';
|
|
68
68
|
export type { HealthHashDescriptor } from './synchronizedEnvHashes.js';
|
|
69
69
|
export { initConsolelog } from './consoleLog.js';
|
|
@@ -89,7 +89,7 @@ export { extractTokenFromRequest } from './extractTokenFromRequest.js';
|
|
|
89
89
|
export { resolveClientIp, isLoopbackIp, UNKNOWN_CLIENT_IP, deriveTokenBucketId } from './resolveClientIp.js';
|
|
90
90
|
export type { ResolveClientIpParams } from './resolveClientIp.js';
|
|
91
91
|
export { registerSessionProvider, getRegisteredSessionProvider, isSessionProviderRegistered, resetSessionProviderForTests, readSession, writeSession, removeSession, performLogout, } from './sessionProviderRegistry.js';
|
|
92
|
-
export type { SessionProvider, SessionSaveResult, SessionLogoutInput } from './sessionProviderRegistry.js';
|
|
92
|
+
export type { SessionProvider, SessionSaveResult, SessionSaveOptions, SessionLogoutInput } from './sessionProviderRegistry.js';
|
|
93
93
|
export { validateRequest, isFalsy } from './validateRequest.js';
|
|
94
94
|
export type { ValidationResult } from './validateRequest.js';
|
|
95
95
|
export { checkRateLimit, getRateLimitStatus, clearRateLimit, clearAllRateLimits, registerRateLimitStrategy, getRateLimitStrategy, defaultRateLimitStrategy, } from './rateLimiter.js';
|
|
@@ -106,5 +106,5 @@ export type { TestResetTarget } from './testResetTargets.js';
|
|
|
106
106
|
export { issueOneTimeToken, consumeOneTimeToken, consumeOneTimeTokenJson, oneTimeTokenKey, } from './oneTimeToken.js';
|
|
107
107
|
export type { OneTimeTokenHandle } from './oneTimeToken.js';
|
|
108
108
|
export { registerHook, dispatchHook, clearAllHooks, registerSyncHook, dispatchSyncHook } from './hooks/registry.js';
|
|
109
|
-
export type { DispatchResult } from './hooks/registry.js';
|
|
109
|
+
export type { DispatchHookOptions, DispatchResult } from './hooks/registry.js';
|
|
110
110
|
export type { HookSessionShape, HookStopSignal, HookResult, HookHandler, HookName, HookPayloads, PreApiValidatePayload, PostApiValidatePayload, PreApiExecutePayload, PostApiExecutePayload, PreApiRespondPayload, PostApiRespondPayload, ApiResponseEnvelope, PreHttpRequestPayload, PostHttpRequestPayload, PreSocketMessagePayload, PreSyncAuthorizePayload, PostSyncAuthorizePayload, PreSyncValidatePayload, PostSyncValidatePayload, PreSyncExecutePayload, PostSyncExecutePayload, PreSyncFanoutPayload, PostSyncFanoutPayload, PreSyncRecipientPayload, ApiErrorPayload, SyncErrorPayload, ApiAuthRejectedPayload, RateLimitExceededPayload, CorsRejectedPayload, CsrfMismatchPayload, PreSessionRefreshPayload, PostSessionRefreshPayload, SessionCreatedPayload, SessionRevokedPayload, OnUploadStartPayload, OnUploadCompletePayload, PreAvatarServePayload, PostAvatarServePayload, PreServerStopPayload, SyncHookName, SyncHookHandler, SyncHookPayloads, PreErrorNormalizePayload, PostErrorNormalizePayload, } from './hooks/types.js';
|
package/dist/index.js
CHANGED
|
@@ -51,7 +51,7 @@ import {
|
|
|
51
51
|
tryCatchSync,
|
|
52
52
|
validatePagePath,
|
|
53
53
|
waitForSocket
|
|
54
|
-
} from "./chunk-
|
|
54
|
+
} from "./chunk-EZIBIQXO.js";
|
|
55
55
|
import {
|
|
56
56
|
getDeployConfig,
|
|
57
57
|
getPortOverride,
|
|
@@ -64,7 +64,7 @@ import {
|
|
|
64
64
|
registerSecretsResolvedListener,
|
|
65
65
|
registerServicesConfig,
|
|
66
66
|
resetPortOverrideForTests
|
|
67
|
-
} from "./chunk-
|
|
67
|
+
} from "./chunk-YKVBUWB6.js";
|
|
68
68
|
import {
|
|
69
69
|
DEFAULT_REDACTED_LOG_KEYS,
|
|
70
70
|
DEPTH_TRUNCATED_PLACEHOLDER,
|
|
@@ -98,7 +98,7 @@ import {
|
|
|
98
98
|
startSpan,
|
|
99
99
|
startSpanAcrossTrackers,
|
|
100
100
|
startSpanHandle
|
|
101
|
-
} from "./chunk-
|
|
101
|
+
} from "./chunk-NJULJZ3N.js";
|
|
102
102
|
import {
|
|
103
103
|
DEFAULT_PROJECT_CONFIG,
|
|
104
104
|
createRegistry,
|
|
@@ -108,7 +108,7 @@ import {
|
|
|
108
108
|
isPlainObject,
|
|
109
109
|
isProjectConfigRegistered,
|
|
110
110
|
registerProjectConfig
|
|
111
|
-
} from "./chunk-
|
|
111
|
+
} from "./chunk-55YXIACQ.js";
|
|
112
112
|
|
|
113
113
|
// src/escapeHtml.ts
|
|
114
114
|
var HTML_ESCAPE_MAP = {
|
|
@@ -170,13 +170,20 @@ var registerHook = (name, handler) => {
|
|
|
170
170
|
if (index !== -1) handlers.splice(index, 1);
|
|
171
171
|
};
|
|
172
172
|
};
|
|
173
|
-
var dispatchHook = async (name, payload) => {
|
|
174
|
-
const handlers = hookHandlers.get(name) ?? [];
|
|
173
|
+
var dispatchHook = async (name, payload, options = {}) => {
|
|
174
|
+
const handlers = [...hookHandlers.get(name) ?? []];
|
|
175
175
|
for (const handler of handlers) {
|
|
176
176
|
let result;
|
|
177
177
|
try {
|
|
178
178
|
result = await handler(payload);
|
|
179
179
|
} catch (error) {
|
|
180
|
+
if (options.onError) {
|
|
181
|
+
try {
|
|
182
|
+
options.onError(error);
|
|
183
|
+
} catch {
|
|
184
|
+
}
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
180
187
|
try {
|
|
181
188
|
getLogger().error(`hook: handler for "${name}" threw`, error, { hook: name });
|
|
182
189
|
} catch {
|
|
@@ -211,7 +218,7 @@ var registerSyncHook = (name, handler) => {
|
|
|
211
218
|
};
|
|
212
219
|
};
|
|
213
220
|
var dispatchSyncHook = (name, payload) => {
|
|
214
|
-
const handlers = syncHookHandlers.get(name) ?? [];
|
|
221
|
+
const handlers = [...syncHookHandlers.get(name) ?? []];
|
|
215
222
|
for (const handler of handlers) {
|
|
216
223
|
try {
|
|
217
224
|
handler(payload);
|
|
@@ -409,8 +416,13 @@ var warnOnBunEnvAutoload = (files) => {
|
|
|
409
416
|
var loadEnvFiles = () => {
|
|
410
417
|
const files = getEnvFiles();
|
|
411
418
|
warnOnBunEnvAutoload(files);
|
|
412
|
-
|
|
413
|
-
|
|
419
|
+
const ambientKeys = new Set(Object.keys(process.env));
|
|
420
|
+
const fileValues = {};
|
|
421
|
+
for (const file of files) {
|
|
422
|
+
loadDotenv({ path: file, processEnv: fileValues, override: true });
|
|
423
|
+
}
|
|
424
|
+
for (const [key, value] of Object.entries(fileValues)) {
|
|
425
|
+
if (!ambientKeys.has(key)) process.env[key] = value;
|
|
414
426
|
}
|
|
415
427
|
if (process.env.LUCKYSTACK_ENV_DEBUG) {
|
|
416
428
|
reportDuplicateEnvKeys(files);
|
|
@@ -472,32 +484,42 @@ var readBound = (target, prop) => {
|
|
|
472
484
|
const value = Reflect.get(target, prop);
|
|
473
485
|
return typeof value === "function" ? value.bind(target) : value;
|
|
474
486
|
};
|
|
475
|
-
var guardSocketsMap = (map) => new Proxy(map, {
|
|
487
|
+
var guardSocketsMap = (map, label) => new Proxy(map, {
|
|
476
488
|
get(target, prop) {
|
|
477
489
|
if (ENUMERATING_MAP_MEMBERS.has(prop)) {
|
|
478
|
-
throw new LocalSocketEnumerationError(
|
|
490
|
+
throw new LocalSocketEnumerationError(`Enumerating \`${label}.sockets\``);
|
|
479
491
|
}
|
|
480
492
|
return readBound(target, prop);
|
|
481
493
|
}
|
|
482
494
|
});
|
|
483
|
-
var guardAdapter = (adapter) => new Proxy(adapter, {
|
|
495
|
+
var guardAdapter = (adapter, label) => new Proxy(adapter, {
|
|
484
496
|
get(target, prop) {
|
|
485
497
|
if (PER_INSTANCE_ADAPTER_MEMBERS.has(prop)) {
|
|
486
|
-
throw new LocalSocketEnumerationError(
|
|
498
|
+
throw new LocalSocketEnumerationError(`\`${label}.adapter.${String(prop)}\``);
|
|
487
499
|
}
|
|
488
500
|
return readBound(target, prop);
|
|
489
501
|
}
|
|
490
502
|
});
|
|
491
|
-
var guardNamespace = (namespace) => new Proxy(namespace, {
|
|
503
|
+
var guardNamespace = (namespace, label) => new Proxy(namespace, {
|
|
492
504
|
get(target, prop) {
|
|
493
|
-
if (prop === "adapter") return guardAdapter(target.adapter);
|
|
494
|
-
if (prop === "sockets") return guardSocketsMap(target.sockets);
|
|
505
|
+
if (prop === "adapter") return guardAdapter(target.adapter, label);
|
|
506
|
+
if (prop === "sockets") return guardSocketsMap(target.sockets, label);
|
|
495
507
|
return readBound(target, prop);
|
|
496
508
|
}
|
|
497
509
|
});
|
|
510
|
+
var isGuardableNamespace = (value) => typeof value === "object" && value !== null && typeof Reflect.get(value, "adapter") === "object" && Reflect.get(value, "sockets") instanceof Map;
|
|
498
511
|
var guardLocalSocketEnumeration = (io) => new Proxy(io, {
|
|
499
512
|
get(target, prop) {
|
|
500
|
-
if (prop === "sockets") return guardNamespace(target.sockets);
|
|
513
|
+
if (prop === "sockets") return guardNamespace(target.sockets, "io.sockets");
|
|
514
|
+
const value = Reflect.get(target, prop);
|
|
515
|
+
if (prop === "of" && typeof value === "function") {
|
|
516
|
+
return (...args) => {
|
|
517
|
+
const namespace = Reflect.apply(value, target, args);
|
|
518
|
+
if (!isGuardableNamespace(namespace)) return namespace;
|
|
519
|
+
const name = args[0];
|
|
520
|
+
return guardNamespace(namespace, typeof name === "string" ? `io.of('${name}')` : "io.of(\u2026)");
|
|
521
|
+
};
|
|
522
|
+
}
|
|
501
523
|
return readBound(target, prop);
|
|
502
524
|
}
|
|
503
525
|
});
|
|
@@ -554,9 +576,7 @@ var registerEmailSender = (sender) => {
|
|
|
554
576
|
};
|
|
555
577
|
var registerEmailSenders = (senders) => {
|
|
556
578
|
registry4 = { ...senders };
|
|
557
|
-
|
|
558
|
-
activeSender = senders.default;
|
|
559
|
-
}
|
|
579
|
+
activeSender = senders.default ?? null;
|
|
560
580
|
};
|
|
561
581
|
var getEmailSender = () => activeSender ?? registry4.default ?? null;
|
|
562
582
|
var getEmailSenderByName = (name) => {
|
|
@@ -585,6 +605,7 @@ var setCurrentErrorTrackerIdentity = (user) => {
|
|
|
585
605
|
if (box) box.user = user;
|
|
586
606
|
};
|
|
587
607
|
var getCurrentErrorTrackerIdentity = () => identityStore.getStore()?.user ?? null;
|
|
608
|
+
var hasErrorTrackerIdentityScope = () => identityStore.getStore() !== void 0;
|
|
588
609
|
|
|
589
610
|
// src/db.ts
|
|
590
611
|
import { createRequire as createRequire2 } from "module";
|
|
@@ -946,6 +967,10 @@ import { createAdapter } from "@socket.io/redis-adapter";
|
|
|
946
967
|
import { randomUUID } from "crypto";
|
|
947
968
|
var BOOT_KEY_PREFIX = "luckystack:boot:";
|
|
948
969
|
var DEFAULT_BOOT_KEY_TTL_SECONDS = 3600;
|
|
970
|
+
var bootUuidKey = (envKey) => {
|
|
971
|
+
const projectName = process.env.PROJECT_NAME;
|
|
972
|
+
return `${BOOT_KEY_PREFIX}${projectName && projectName.length > 0 ? projectName : "luckystack"}:${envKey}`;
|
|
973
|
+
};
|
|
949
974
|
var getBootKeyTtlSeconds = () => getDeployConfig().routing?.bootKeyTtlSeconds ?? DEFAULT_BOOT_KEY_TTL_SECONDS;
|
|
950
975
|
var getBootUuidRefreshIntervalMs = () => Math.max(100, Math.floor(getBootKeyTtlSeconds() * 1e3 / 3));
|
|
951
976
|
var resolveEnvKey = () => {
|
|
@@ -954,16 +979,16 @@ var resolveEnvKey = () => {
|
|
|
954
979
|
var writeBootUuid = async (envKey) => {
|
|
955
980
|
const key = envKey ?? resolveEnvKey();
|
|
956
981
|
const uuid = randomUUID();
|
|
957
|
-
await redis.set(
|
|
982
|
+
await redis.set(bootUuidKey(key), uuid, "EX", getBootKeyTtlSeconds());
|
|
958
983
|
return uuid;
|
|
959
984
|
};
|
|
960
985
|
var readBootUuid = async (envKey) => {
|
|
961
986
|
const key = envKey ?? resolveEnvKey();
|
|
962
|
-
return redis.get(
|
|
987
|
+
return redis.get(bootUuidKey(key));
|
|
963
988
|
};
|
|
964
989
|
var refreshBootUuid = async (envKey) => {
|
|
965
990
|
const key = envKey ?? resolveEnvKey();
|
|
966
|
-
const refreshed = await redis.expire(
|
|
991
|
+
const refreshed = await redis.expire(bootUuidKey(key), getBootKeyTtlSeconds());
|
|
967
992
|
if (refreshed === 0) await writeBootUuid(key);
|
|
968
993
|
};
|
|
969
994
|
var startBootUuidHeartbeat = (envKey) => {
|
|
@@ -980,7 +1005,7 @@ var startBootUuidHeartbeat = (envKey) => {
|
|
|
980
1005
|
},
|
|
981
1006
|
(error) => {
|
|
982
1007
|
getLogger().error(
|
|
983
|
-
`[boot-uuid] failed to refresh ${
|
|
1008
|
+
`[boot-uuid] failed to refresh ${bootUuidKey(key)}; readiness may degrade if the TTL expires`,
|
|
984
1009
|
error instanceof Error ? error : new Error(String(error))
|
|
985
1010
|
);
|
|
986
1011
|
schedule();
|
|
@@ -1110,7 +1135,10 @@ var initConsolelog = () => {
|
|
|
1110
1135
|
originalLog(`${colorCode}${extractedInfo}${COLORS.reset}`);
|
|
1111
1136
|
originalLog(...args);
|
|
1112
1137
|
} else {
|
|
1113
|
-
|
|
1138
|
+
const firstNonString = args.findIndex((arg) => typeof arg !== "string");
|
|
1139
|
+
const leading = firstNonString === -1 ? args : args.slice(0, firstNonString);
|
|
1140
|
+
const rest = firstNonString === -1 ? [] : args.slice(firstNonString);
|
|
1141
|
+
originalLog(`${colorCode}${extractedInfo} -- ${leading.join(" ")}${COLORS.reset}`, ...rest);
|
|
1114
1142
|
}
|
|
1115
1143
|
};
|
|
1116
1144
|
};
|
|
@@ -1440,7 +1468,8 @@ var extractTokenFromSocket = (socket2) => {
|
|
|
1440
1468
|
const config = getProjectConfig();
|
|
1441
1469
|
const cookie = socket2.handshake.headers.cookie;
|
|
1442
1470
|
const sessionToken = typeof socket2.handshake.auth.token === "string" ? socket2.handshake.auth.token : null;
|
|
1443
|
-
const
|
|
1471
|
+
const cookieName = applyCookiePrefixConstraints(config.http.sessionCookieName, config.http.sessionCookiePrefix).name;
|
|
1472
|
+
const cookieToken = getCookieValue(cookie, cookieName);
|
|
1444
1473
|
if (config.session.basedToken) {
|
|
1445
1474
|
return sessionToken ?? cookieToken;
|
|
1446
1475
|
}
|
|
@@ -1456,7 +1485,8 @@ var extractTokenFromRequest = (req) => {
|
|
|
1456
1485
|
const authHeader = typeof rawAuthHeader === "string" ? rawAuthHeader : Array.isArray(rawAuthHeader) && typeof rawAuthHeader[0] === "string" ? rawAuthHeader[0] : void 0;
|
|
1457
1486
|
const bearerToken = authHeader?.startsWith("Bearer ") ? authHeader.slice(7) : null;
|
|
1458
1487
|
const config = getProjectConfig();
|
|
1459
|
-
const
|
|
1488
|
+
const cookieName = applyCookiePrefixConstraints(config.http.sessionCookieName, config.http.sessionCookiePrefix).name;
|
|
1489
|
+
const cookieToken = getCookieValue(req.headers.cookie, cookieName);
|
|
1460
1490
|
if (config.session.basedToken) {
|
|
1461
1491
|
return bearerToken ?? cookieToken;
|
|
1462
1492
|
}
|
|
@@ -1948,6 +1978,36 @@ var parseObjectFields = (typeText) => {
|
|
|
1948
1978
|
}
|
|
1949
1979
|
return { fields, indexSignatures };
|
|
1950
1980
|
};
|
|
1981
|
+
var wrapsWhole = (text, open, close) => {
|
|
1982
|
+
if (!text.startsWith(open) || !text.endsWith(close)) return false;
|
|
1983
|
+
let depth = 0;
|
|
1984
|
+
let inString = null;
|
|
1985
|
+
for (let index = 0; index < text.length; index += 1) {
|
|
1986
|
+
const char = text[index];
|
|
1987
|
+
if (inString) {
|
|
1988
|
+
if (char === "\\") index += 1;
|
|
1989
|
+
else if (char === inString) inString = null;
|
|
1990
|
+
continue;
|
|
1991
|
+
}
|
|
1992
|
+
if (char === '"' || char === "'") {
|
|
1993
|
+
inString = char;
|
|
1994
|
+
continue;
|
|
1995
|
+
}
|
|
1996
|
+
if (char === open) depth += 1;
|
|
1997
|
+
if (char === close) {
|
|
1998
|
+
depth -= 1;
|
|
1999
|
+
if (depth === 0) return index === text.length - 1;
|
|
2000
|
+
}
|
|
2001
|
+
}
|
|
2002
|
+
return false;
|
|
2003
|
+
};
|
|
2004
|
+
var unwrapParens = (text) => {
|
|
2005
|
+
let current = text.trim();
|
|
2006
|
+
while (wrapsWhole(current, "(", ")")) current = current.slice(1, -1).trim();
|
|
2007
|
+
return current;
|
|
2008
|
+
};
|
|
2009
|
+
var isObjectTypeText = (text) => wrapsWhole(text, "{", "}");
|
|
2010
|
+
var unquoteLiteral = (literal) => literal.slice(1, -1).replaceAll(/\\(['"\\])/g, "$1");
|
|
1951
2011
|
var matchesIndexKeyType = ({ keyType, key }) => {
|
|
1952
2012
|
const normalized = keyType.trim();
|
|
1953
2013
|
if (normalized === "string") return true;
|
|
@@ -1957,7 +2017,7 @@ var matchesIndexKeyType = ({ keyType, key }) => {
|
|
|
1957
2017
|
return parts.some((part) => matchesIndexKeyType({ keyType: part, key }));
|
|
1958
2018
|
}
|
|
1959
2019
|
if (normalized.startsWith("'") && normalized.endsWith("'") || normalized.startsWith('"') && normalized.endsWith('"')) {
|
|
1960
|
-
return key === normalized
|
|
2020
|
+
return key === unquoteLiteral(normalized);
|
|
1961
2021
|
}
|
|
1962
2022
|
return false;
|
|
1963
2023
|
};
|
|
@@ -2003,6 +2063,45 @@ var parseRecordParts = (type) => {
|
|
|
2003
2063
|
return null;
|
|
2004
2064
|
};
|
|
2005
2065
|
var MAX_VALIDATION_DEPTH = 64;
|
|
2066
|
+
var JSON_DATA_TYPES = /* @__PURE__ */ new Set(["JsonValue", "JsonObject", "JsonArray", "JsonPrimitive"]);
|
|
2067
|
+
var isJsonPrimitive = (value) => value === null || typeof value === "string" || typeof value === "boolean" || typeof value === "number" && Number.isFinite(value);
|
|
2068
|
+
var isPlainObject2 = (value) => {
|
|
2069
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
|
|
2070
|
+
const prototype = Object.getPrototypeOf(value);
|
|
2071
|
+
return prototype === Object.prototype || prototype === null;
|
|
2072
|
+
};
|
|
2073
|
+
var validateJsonData = (type, value, path4, depth) => {
|
|
2074
|
+
if (depth > MAX_VALIDATION_DEPTH) {
|
|
2075
|
+
return { status: "error", message: `${path4}: input nesting exceeds the maximum depth of ${String(MAX_VALIDATION_DEPTH)}` };
|
|
2076
|
+
}
|
|
2077
|
+
if (isJsonPrimitive(value)) {
|
|
2078
|
+
return type === "JsonValue" || type === "JsonPrimitive" ? { status: "success" } : { status: "error", message: `${path4} should be ${type === "JsonArray" ? "a JSON array" : "a JSON object"}` };
|
|
2079
|
+
}
|
|
2080
|
+
if (type === "JsonPrimitive") {
|
|
2081
|
+
return { status: "error", message: `${path4} should be a JSON primitive` };
|
|
2082
|
+
}
|
|
2083
|
+
if (Array.isArray(value)) {
|
|
2084
|
+
if (type === "JsonObject") return { status: "error", message: `${path4} should be a JSON object` };
|
|
2085
|
+
for (const [index, element] of value.entries()) {
|
|
2086
|
+
const result = validateJsonData("JsonValue", element, `${path4}[${String(index)}]`, depth + 1);
|
|
2087
|
+
if (result.status === "error") return result;
|
|
2088
|
+
}
|
|
2089
|
+
return { status: "success" };
|
|
2090
|
+
}
|
|
2091
|
+
if (isPlainObject2(value)) {
|
|
2092
|
+
if (type === "JsonArray") return { status: "error", message: `${path4} should be a JSON array` };
|
|
2093
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
2094
|
+
if (PROTO_POLLUTION_KEYS.has(key)) {
|
|
2095
|
+
return { status: "error", message: `${path4}.${key} is not allowed` };
|
|
2096
|
+
}
|
|
2097
|
+
if (entry === void 0) continue;
|
|
2098
|
+
const result = validateJsonData("JsonValue", entry, `${path4}.${key}`, depth + 1);
|
|
2099
|
+
if (result.status === "error") return result;
|
|
2100
|
+
}
|
|
2101
|
+
return { status: "success" };
|
|
2102
|
+
}
|
|
2103
|
+
return { status: "error", message: `${path4} should be JSON data` };
|
|
2104
|
+
};
|
|
2006
2105
|
var validateType = (typeText, value, path4, depth = 0) => {
|
|
2007
2106
|
if (depth > MAX_VALIDATION_DEPTH) {
|
|
2008
2107
|
return { status: "error", message: `${path4}: input nesting exceeds the maximum depth of ${String(MAX_VALIDATION_DEPTH)}` };
|
|
@@ -2032,14 +2131,20 @@ var validateType = (typeText, value, path4, depth = 0) => {
|
|
|
2032
2131
|
if (type.includes("&")) {
|
|
2033
2132
|
const intersectionParts = splitTopLevel(type, "&").filter(Boolean);
|
|
2034
2133
|
if (intersectionParts.length > 1) {
|
|
2134
|
+
const objectParts = intersectionParts.map((part) => unwrapParens(part));
|
|
2135
|
+
if (objectParts.every((part) => isObjectTypeText(part))) {
|
|
2136
|
+
const mergedBody = objectParts.map((part) => part.slice(1, -1)).join("; ");
|
|
2137
|
+
return validateType(`{ ${mergedBody} }`, value, path4, depth + 1);
|
|
2138
|
+
}
|
|
2035
2139
|
for (const intersectionType of intersectionParts) {
|
|
2036
2140
|
const result = validateType(intersectionType, value, path4, depth + 1);
|
|
2037
2141
|
if (result.status === "error") return result;
|
|
2038
2142
|
}
|
|
2039
2143
|
return { status: "success" };
|
|
2040
2144
|
}
|
|
2041
|
-
|
|
2042
|
-
|
|
2145
|
+
const singleMember = intersectionParts[0] ?? type;
|
|
2146
|
+
if (intersectionParts.length === 1 && singleMember !== type) {
|
|
2147
|
+
return validateType(singleMember, value, path4, depth + 1);
|
|
2043
2148
|
}
|
|
2044
2149
|
}
|
|
2045
2150
|
if (type.endsWith("[]")) {
|
|
@@ -2057,7 +2162,7 @@ var validateType = (typeText, value, path4, depth = 0) => {
|
|
|
2057
2162
|
return { status: "success" };
|
|
2058
2163
|
}
|
|
2059
2164
|
if (type.startsWith("'") && type.endsWith("'") || type.startsWith('"') && type.endsWith('"')) {
|
|
2060
|
-
const literal = type
|
|
2165
|
+
const literal = unquoteLiteral(type);
|
|
2061
2166
|
return value === literal ? { status: "success" } : { status: "error", message: `${path4} should equal ${literal}` };
|
|
2062
2167
|
}
|
|
2063
2168
|
const numericLiteral = parseFiniteNumericLiteral(type);
|
|
@@ -2074,6 +2179,9 @@ var validateType = (typeText, value, path4, depth = 0) => {
|
|
|
2074
2179
|
if (type === "any" || type === "unknown") {
|
|
2075
2180
|
return { status: "success" };
|
|
2076
2181
|
}
|
|
2182
|
+
if (JSON_DATA_TYPES.has(type)) {
|
|
2183
|
+
return validateJsonData(type, value, path4, depth);
|
|
2184
|
+
}
|
|
2077
2185
|
if (/^Record<.+>$/.test(type)) {
|
|
2078
2186
|
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
2079
2187
|
return { status: "error", message: `${path4} should be an object` };
|
|
@@ -2164,7 +2272,7 @@ var validateInputByType = async ({
|
|
|
2164
2272
|
return { status: "success" };
|
|
2165
2273
|
}
|
|
2166
2274
|
if (isProductionRuntime()) {
|
|
2167
|
-
const { getProjectConfig: getProjectConfig2 } = await import("./projectConfig-
|
|
2275
|
+
const { getProjectConfig: getProjectConfig2 } = await import("./projectConfig-6QNMG5GZ.js");
|
|
2168
2276
|
if (getProjectConfig2().validation.runtimeMode === "off") {
|
|
2169
2277
|
return { status: "success" };
|
|
2170
2278
|
}
|
|
@@ -2371,6 +2479,7 @@ export {
|
|
|
2371
2479
|
applySocketMiddlewares,
|
|
2372
2480
|
applyStrayKeyPrefix,
|
|
2373
2481
|
attachSocketRedisAdapter,
|
|
2482
|
+
bootUuidKey,
|
|
2374
2483
|
bootstrapEnv,
|
|
2375
2484
|
buildApiResponseEventName,
|
|
2376
2485
|
buildApiStreamEventName,
|
|
@@ -2475,6 +2584,7 @@ export {
|
|
|
2475
2584
|
getSyncQueueSize,
|
|
2476
2585
|
getUploadsDir,
|
|
2477
2586
|
hasCookie,
|
|
2587
|
+
hasErrorTrackerIdentityScope,
|
|
2478
2588
|
hashSynchronizedValue,
|
|
2479
2589
|
hashSynchronizedValueWith,
|
|
2480
2590
|
httpFetch,
|