veryfront 0.1.45 → 0.1.46
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/esm/deno.js +1 -1
- package/esm/src/platform/adapters/fs/veryfront/content-metrics.js +1 -1
- package/esm/src/platform/adapters/fs/veryfront/read-operations.js +2 -2
- package/esm/src/platform/adapters/fs/veryfront/websocket-manager.js +1 -1
- package/esm/src/proxy/handler.d.ts.map +1 -1
- package/esm/src/proxy/handler.js +61 -15
- package/esm/src/server/bootstrap.d.ts.map +1 -1
- package/esm/src/server/bootstrap.js +2 -1
- package/esm/src/utils/index.d.ts +1 -1
- package/esm/src/utils/index.d.ts.map +1 -1
- package/esm/src/utils/index.js +1 -1
- package/esm/src/utils/logger/index.d.ts +1 -1
- package/esm/src/utils/logger/index.d.ts.map +1 -1
- package/esm/src/utils/logger/index.js +1 -1
- package/esm/src/utils/logger/logger.d.ts +10 -9
- package/esm/src/utils/logger/logger.d.ts.map +1 -1
- package/esm/src/utils/logger/logger.js +47 -59
- package/package.json +1 -1
- package/src/deno.js +1 -1
- package/src/src/platform/adapters/fs/veryfront/content-metrics.ts +1 -1
- package/src/src/platform/adapters/fs/veryfront/read-operations.ts +2 -2
- package/src/src/platform/adapters/fs/veryfront/websocket-manager.ts +1 -1
- package/src/src/proxy/handler.ts +90 -17
- package/src/src/server/bootstrap.ts +2 -1
- package/src/src/utils/index.ts +1 -0
- package/src/src/utils/logger/index.ts +1 -0
- package/src/src/utils/logger/logger.ts +54 -69
package/esm/deno.js
CHANGED
|
@@ -61,7 +61,7 @@ export function endRequestMetrics(requestContext) {
|
|
|
61
61
|
cumulativeMetrics.totalNetworkMs += req.networkMs;
|
|
62
62
|
cumulativeMetrics.requestsTracked++;
|
|
63
63
|
recordContentNetworkFetch(req.networkMs, req.isPreviewMode ?? false);
|
|
64
|
-
logger.
|
|
64
|
+
logger.debug("REQUEST_SUMMARY", {
|
|
65
65
|
...requestContext,
|
|
66
66
|
durationMs,
|
|
67
67
|
networkMs: req.networkMs,
|
|
@@ -400,13 +400,13 @@ export class ReadOperations {
|
|
|
400
400
|
return null;
|
|
401
401
|
}
|
|
402
402
|
async fetchDraftContent(normalizedPath, apiPath, cacheKey, shouldCache) {
|
|
403
|
-
logger.
|
|
403
|
+
logger.debug("API_FETCH_START - fetching draft from API", {
|
|
404
404
|
path: normalizedPath,
|
|
405
405
|
apiPath,
|
|
406
406
|
cacheKey,
|
|
407
407
|
});
|
|
408
408
|
const content = await this.client.getFileContent(apiPath);
|
|
409
|
-
logger.
|
|
409
|
+
logger.debug("API_FETCH_DONE - got content from API", {
|
|
410
410
|
path: normalizedPath,
|
|
411
411
|
contentLength: content.length,
|
|
412
412
|
preview: previewText(content).replace(/\n/g, "\\n"),
|
|
@@ -70,7 +70,7 @@ export class WebSocketManager {
|
|
|
70
70
|
};
|
|
71
71
|
this.ws.onmessage = (event) => {
|
|
72
72
|
this.wsLastPong = Date.now();
|
|
73
|
-
logger.
|
|
73
|
+
logger.debug("WebSocket message received:", { data: event.data });
|
|
74
74
|
this.handlePokeMessage(event);
|
|
75
75
|
};
|
|
76
76
|
this.ws.onclose = () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/src/proxy/handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,qBAAqB,CAAC;AAE/C,OAAO,EAAE,KAAK,YAAY,EAAsB,MAAM,kCAAkC,CAAC;AACzF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAOnD,eAAO,MAAM,sBAAsB,0MAYzB,CAAC;
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/src/proxy/handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,qBAAqB,CAAC;AAE/C,OAAO,EAAE,KAAK,YAAY,EAAsB,MAAM,kCAAkC,CAAC;AACzF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAOnD,eAAO,MAAM,sBAAsB,0MAYzB,CAAC;AA6EX,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,SAAS,GAAG,YAAY,CAAC;IACtC,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,YAAY,CAAC;IAC3B,cAAc,EAAE,OAAO,CAAC;IACxB,KAAK,CAAC,EAAE;QACN,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;CACH;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IAC9D,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IAC7D,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IAC7D,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;CAC9E;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,WAAW,CAAC;IACpB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAmCD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,mBAAmB;0BA6K1B,OAAO,CAAC,OAAO,KAAG,OAAO,CAAC,YAAY,CAAC;0BA+NvC,OAAO,CAAC,OAAO,KAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;;;;;;;;0BAlVrD,MAAM,EAAE;;EAgYpC;AAED,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAEjE,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAwB7F"}
|
package/esm/src/proxy/handler.js
CHANGED
|
@@ -69,6 +69,30 @@ function extractUserToken(cookieHeader) {
|
|
|
69
69
|
const match = cookieHeader.match(/(?:^|;\s*)authToken=([^;]+)/);
|
|
70
70
|
return match?.[1] ? decodeURIComponent(match[1]) : undefined;
|
|
71
71
|
}
|
|
72
|
+
function extractUserIdFromToken(token) {
|
|
73
|
+
try {
|
|
74
|
+
const payload = token.split(".")[1];
|
|
75
|
+
if (!payload)
|
|
76
|
+
return undefined;
|
|
77
|
+
// JWT payloads are base64url-encoded: normalize to standard base64 before decoding
|
|
78
|
+
let base64 = payload.replace(/-/g, "+").replace(/_/g, "/");
|
|
79
|
+
const remainder = base64.length % 4;
|
|
80
|
+
if (remainder === 2)
|
|
81
|
+
base64 += "==";
|
|
82
|
+
else if (remainder === 3)
|
|
83
|
+
base64 += "=";
|
|
84
|
+
const decoded = JSON.parse(atob(base64));
|
|
85
|
+
return decoded?.userId;
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function isProjectMember(users, userId) {
|
|
92
|
+
if (!users || !userId)
|
|
93
|
+
return false;
|
|
94
|
+
return users.some((u) => u.id === userId);
|
|
95
|
+
}
|
|
72
96
|
export function createProxyHandler(options) {
|
|
73
97
|
const { config, cache, logger } = options;
|
|
74
98
|
const localProjects = config.localProjects ?? {};
|
|
@@ -145,20 +169,47 @@ export function createProxyHandler(options) {
|
|
|
145
169
|
const returnPath = safePath + url.search;
|
|
146
170
|
return `https://veryfront.com/sign-in?from=${encodeURIComponent(returnPath)}`;
|
|
147
171
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
const matchingEnv = lookupResult.environments?.find(envMatcher);
|
|
153
|
-
if (matchingEnv?.protected && !userToken) {
|
|
172
|
+
function checkProtectedAccess(req, matchingEnv, userToken, users, logContext) {
|
|
173
|
+
if (!matchingEnv?.protected)
|
|
174
|
+
return null;
|
|
175
|
+
if (!userToken) {
|
|
154
176
|
const redirectUrl = makeAuthRedirectUrl(req);
|
|
155
177
|
logger?.info("Protected environment requires authentication", {
|
|
156
178
|
...logContext,
|
|
157
179
|
environmentName: matchingEnv.name,
|
|
158
180
|
redirectUrl,
|
|
159
181
|
});
|
|
160
|
-
return {
|
|
182
|
+
return { status: 302, message: "Authentication required", redirectUrl };
|
|
183
|
+
}
|
|
184
|
+
const userId = extractUserIdFromToken(userToken);
|
|
185
|
+
if (!userId) {
|
|
186
|
+
// Malformed token — treat as unauthenticated so user can re-sign-in
|
|
187
|
+
const redirectUrl = makeAuthRedirectUrl(req);
|
|
188
|
+
logger?.info("Could not extract userId from token", {
|
|
189
|
+
...logContext,
|
|
190
|
+
environmentName: matchingEnv.name,
|
|
191
|
+
redirectUrl,
|
|
192
|
+
});
|
|
193
|
+
return { status: 302, message: "Authentication required", redirectUrl };
|
|
194
|
+
}
|
|
195
|
+
if (!isProjectMember(users, userId)) {
|
|
196
|
+
logger?.info("User is not a member of the project", {
|
|
197
|
+
...logContext,
|
|
198
|
+
environmentName: matchingEnv.name,
|
|
199
|
+
userId,
|
|
200
|
+
});
|
|
201
|
+
return { status: 403, message: "Access denied" };
|
|
161
202
|
}
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
async function resolveReleaseAndProtection(req, token, userToken, lookupKey, envMatcher, logContext) {
|
|
206
|
+
const lookupResult = await lookupProjectByDomain(lookupKey, config.apiBaseUrl, token, logger);
|
|
207
|
+
if (!lookupResult)
|
|
208
|
+
return { projectId: undefined, releaseId: undefined };
|
|
209
|
+
const matchingEnv = lookupResult.environments?.find(envMatcher);
|
|
210
|
+
const protectionError = checkProtectedAccess(req, matchingEnv, userToken, lookupResult.users, logContext);
|
|
211
|
+
if (protectionError)
|
|
212
|
+
return { error: protectionError };
|
|
162
213
|
return {
|
|
163
214
|
projectId: lookupResult.id,
|
|
164
215
|
releaseId: matchingEnv?.active_release_id ?? undefined,
|
|
@@ -240,14 +291,9 @@ export function createProxyHandler(options) {
|
|
|
240
291
|
const matchingEnv = lookupResult.environments?.find((env) => env.domains?.some((d) => d.toLowerCase() === normalizedHost));
|
|
241
292
|
releaseId = matchingEnv?.active_release_id ?? undefined;
|
|
242
293
|
environmentId = matchingEnv?.id;
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
domain: host,
|
|
247
|
-
environmentName: matchingEnv.name,
|
|
248
|
-
redirectUrl,
|
|
249
|
-
});
|
|
250
|
-
return makeErrorContext(base, 302, "Authentication required", token, redirectUrl);
|
|
294
|
+
const protectionError = checkProtectedAccess(req, matchingEnv, userToken, lookupResult.users, { domain: host });
|
|
295
|
+
if (protectionError) {
|
|
296
|
+
return makeErrorContext(base, protectionError.status, protectionError.message, token, protectionError.redirectUrl);
|
|
251
297
|
}
|
|
252
298
|
logger?.info("Resolved custom domain to project", {
|
|
253
299
|
domain: host,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../../src/src/server/bootstrap.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AA4B1D,MAAM,WAAW,eAAe;IAC9B,8DAA8D;IAC9D,OAAO,EAAE,cAAc,CAAC;IAExB,2BAA2B;IAC3B,MAAM,EAAE,eAAe,CAAC;IAExB,wCAAwC;IACxC,cAAc,EAAE,OAAO,CAAC;IAExB,+BAA+B;IAC/B,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,kEAAkE;IAClE,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;
|
|
1
|
+
{"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../../src/src/server/bootstrap.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AA4B1D,MAAM,WAAW,eAAe;IAC9B,8DAA8D;IAC9D,OAAO,EAAE,cAAc,CAAC;IAExB,2BAA2B;IAC3B,MAAM,EAAE,eAAe,CAAC;IAExB,wCAAwC;IACxC,cAAc,EAAE,OAAO,CAAC;IAExB,+BAA+B;IAC/B,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,kEAAkE;IAClE,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAmDD,wBAAsB,SAAS,CAC7B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,eAAe,CAAC,CAqG1B;AAED,wBAAsB,YAAY,CAChC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,eAAe,CAAC,CAa1B;AAED,wBAAsB,aAAa,CACjC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,eAAe,CAAC,CAyB1B"}
|
|
@@ -5,7 +5,7 @@ import { enhanceAdapterWithFS } from "../platform/adapters/fs/integration.js";
|
|
|
5
5
|
import { isExtendedFSAdapter } from "../platform/adapters/fs/wrapper.js";
|
|
6
6
|
import { getEnv } from "../platform/compat/process.js";
|
|
7
7
|
import { initializeEsbuild } from "../platform/compat/esbuild.js";
|
|
8
|
-
import { logger } from "../utils/index.js";
|
|
8
|
+
import { logger, refreshLoggerConfig } from "../utils/index.js";
|
|
9
9
|
import { isDebugEnabled } from "../utils/constants/env.js";
|
|
10
10
|
import { getEnvSource, hasEnvLoaded, loadEnv, markEnvLoaded, supportsEnvFiles, } from "../utils/env-loader.js";
|
|
11
11
|
import { ReloadNotifier } from "./reload-notifier.js";
|
|
@@ -26,6 +26,7 @@ async function ensureEnvLoaded(projectDir, adapter) {
|
|
|
26
26
|
debug: isDebugEnabled(adapter.env),
|
|
27
27
|
});
|
|
28
28
|
refreshEnvironmentConfig();
|
|
29
|
+
refreshLoggerConfig();
|
|
29
30
|
}
|
|
30
31
|
catch (error) {
|
|
31
32
|
bootstrapLog.warn("Failed to load .env files", {
|
package/esm/src/utils/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* @module utils
|
|
6
6
|
*/
|
|
7
7
|
export { type GlobalWithBun, type GlobalWithDeno, type GlobalWithProcess, hasBunRuntime, hasDenoRuntime, hasNodeProcess, } from "./runtime-guards.js";
|
|
8
|
-
export { agentLogger, bundlerLogger, logger, rendererLogger, serverLogger, } from "./logger/index.js";
|
|
8
|
+
export { agentLogger, bundlerLogger, logger, refreshLoggerConfig, rendererLogger, serverLogger, } from "./logger/index.js";
|
|
9
9
|
export { BREAKPOINT_LG, BREAKPOINT_MD, BREAKPOINT_SM, BREAKPOINT_XL, BYTES_PER_KB, DEFAULT_ALLOWED_CDN_HOSTS, DEFAULT_BUILD_CONCURRENCY, DEFAULT_DASHBOARD_PORT, DEFAULT_LRU_MAX_ENTRIES, DEV_SERVER_ENDPOINTS, FORBIDDEN_PATH_PATTERNS, getDenoStdNodeBase, getReactImportMap, HASH_SEED_DJB2, HASH_SEED_FNV1A, HMR_CLIENT_RELOAD_DELAY_MS, HMR_CLOSE_MESSAGE_TOO_LARGE, HMR_CLOSE_NORMAL, HMR_CLOSE_RATE_LIMIT, HMR_MAX_MESSAGE_SIZE_BYTES, HMR_MAX_MESSAGES_PER_MINUTE, HMR_RATE_LIMIT_WINDOW_MS, HTTP_BAD_REQUEST, HTTP_CONTENT_TYPE_IMAGE_GIF, HTTP_CONTENT_TYPE_IMAGE_ICO, HTTP_CONTENT_TYPE_IMAGE_JPEG, HTTP_CONTENT_TYPE_IMAGE_PNG, HTTP_CONTENT_TYPE_IMAGE_SVG, HTTP_CONTENT_TYPE_IMAGE_WEBP, HTTP_CONTENT_TYPES, HTTP_MODULE_FETCH_TIMEOUT_MS, HTTP_NETWORK_CONNECT_TIMEOUT, HTTP_NOT_FOUND, HTTP_NOT_IMPLEMENTED, HTTP_OK, HTTP_REDIRECT_FOUND, HTTP_SERVER_ERROR, HTTP_STATUS_CLIENT_ERROR_MIN, HTTP_STATUS_REDIRECT_MIN, HTTP_STATUS_SERVER_ERROR_MIN, HTTP_STATUS_SUCCESS_MIN, HTTP_UNAVAILABLE, IMAGE_OPTIMIZATION, MAX_BATCH_SIZE, MAX_PATH_LENGTH, MAX_PATH_TRAVERSAL_DEPTH, MS_PER_SECOND, PREFETCH_DEFAULT_DELAY_MS, PREFETCH_DEFAULT_TIMEOUT_MS, PREFETCH_MAX_SIZE_BYTES, REACT_DEFAULT_VERSION, RESPONSIVE_IMAGE_WIDTH_LG, RESPONSIVE_IMAGE_WIDTHS, RSC_MANIFEST_CACHE_TTL_MS, TSX_LAYOUT_MAX_ENTRIES, Z_INDEX_DEV_INDICATOR, Z_INDEX_ERROR_OVERLAY, } from "./constants/index.js";
|
|
10
10
|
export { VERSION } from "./version.js";
|
|
11
11
|
export { type BundleCode as HashBundleCode, computeCodeHash, computeHash, fnv1aHash, shortHash, simpleHash, } from "./hash-utils.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/src/utils/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,aAAa,EACb,cAAc,EACd,cAAc,GACf,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,WAAW,EACX,aAAa,EACb,MAAM,EACN,cAAc,EACd,YAAY,GACb,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,aAAa,EACb,aAAa,EACb,aAAa,EACb,aAAa,EACb,YAAY,EACZ,yBAAyB,EACzB,yBAAyB,EACzB,sBAAsB,EACtB,uBAAuB,EACvB,oBAAoB,EACpB,uBAAuB,EACvB,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,0BAA0B,EAC1B,2BAA2B,EAC3B,gBAAgB,EAChB,oBAAoB,EACpB,0BAA0B,EAC1B,2BAA2B,EAC3B,wBAAwB,EACxB,gBAAgB,EAChB,2BAA2B,EAC3B,2BAA2B,EAC3B,4BAA4B,EAC5B,2BAA2B,EAC3B,2BAA2B,EAC3B,4BAA4B,EAC5B,kBAAkB,EAClB,4BAA4B,EAC5B,4BAA4B,EAC5B,cAAc,EACd,oBAAoB,EACpB,OAAO,EACP,mBAAmB,EACnB,iBAAiB,EACjB,4BAA4B,EAC5B,wBAAwB,EACxB,4BAA4B,EAC5B,uBAAuB,EACvB,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,wBAAwB,EACxB,aAAa,EACb,yBAAyB,EACzB,2BAA2B,EAC3B,uBAAuB,EACvB,qBAAqB,EACrB,yBAAyB,EACzB,uBAAuB,EACvB,yBAAyB,EACzB,sBAAsB,EACtB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,OAAO,EACL,KAAK,UAAU,IAAI,cAAc,EACjC,eAAe,EACf,WAAW,EACX,SAAS,EACT,SAAS,EACT,UAAU,GACX,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,YAAY,EAAE,UAAU,IAAI,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3F,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,cAAc,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAEpG,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,EACL,gBAAgB,EAChB,qBAAqB,EACrB,KAAK,eAAe,GACrB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE7F,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/src/utils/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,aAAa,EACb,cAAc,EACd,cAAc,GACf,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,WAAW,EACX,aAAa,EACb,MAAM,EACN,mBAAmB,EACnB,cAAc,EACd,YAAY,GACb,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,aAAa,EACb,aAAa,EACb,aAAa,EACb,aAAa,EACb,YAAY,EACZ,yBAAyB,EACzB,yBAAyB,EACzB,sBAAsB,EACtB,uBAAuB,EACvB,oBAAoB,EACpB,uBAAuB,EACvB,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,0BAA0B,EAC1B,2BAA2B,EAC3B,gBAAgB,EAChB,oBAAoB,EACpB,0BAA0B,EAC1B,2BAA2B,EAC3B,wBAAwB,EACxB,gBAAgB,EAChB,2BAA2B,EAC3B,2BAA2B,EAC3B,4BAA4B,EAC5B,2BAA2B,EAC3B,2BAA2B,EAC3B,4BAA4B,EAC5B,kBAAkB,EAClB,4BAA4B,EAC5B,4BAA4B,EAC5B,cAAc,EACd,oBAAoB,EACpB,OAAO,EACP,mBAAmB,EACnB,iBAAiB,EACjB,4BAA4B,EAC5B,wBAAwB,EACxB,4BAA4B,EAC5B,uBAAuB,EACvB,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,wBAAwB,EACxB,aAAa,EACb,yBAAyB,EACzB,2BAA2B,EAC3B,uBAAuB,EACvB,qBAAqB,EACrB,yBAAyB,EACzB,uBAAuB,EACvB,yBAAyB,EACzB,sBAAsB,EACtB,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,OAAO,EACL,KAAK,UAAU,IAAI,cAAc,EACjC,eAAe,EACf,WAAW,EACX,SAAS,EACT,SAAS,EACT,UAAU,GACX,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,YAAY,EAAE,UAAU,IAAI,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3F,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,OAAO,EAAE,KAAK,UAAU,EAAE,KAAK,cAAc,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAEpG,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,EACL,gBAAgB,EAChB,qBAAqB,EACrB,KAAK,eAAe,GACrB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE7F,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC"}
|
package/esm/src/utils/index.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* @module utils
|
|
6
6
|
*/
|
|
7
7
|
export { hasBunRuntime, hasDenoRuntime, hasNodeProcess, } from "./runtime-guards.js";
|
|
8
|
-
export { agentLogger, bundlerLogger, logger, rendererLogger, serverLogger, } from "./logger/index.js";
|
|
8
|
+
export { agentLogger, bundlerLogger, logger, refreshLoggerConfig, rendererLogger, serverLogger, } from "./logger/index.js";
|
|
9
9
|
export { BREAKPOINT_LG, BREAKPOINT_MD, BREAKPOINT_SM, BREAKPOINT_XL, BYTES_PER_KB, DEFAULT_ALLOWED_CDN_HOSTS, DEFAULT_BUILD_CONCURRENCY, DEFAULT_DASHBOARD_PORT, DEFAULT_LRU_MAX_ENTRIES, DEV_SERVER_ENDPOINTS, FORBIDDEN_PATH_PATTERNS, getDenoStdNodeBase, getReactImportMap, HASH_SEED_DJB2, HASH_SEED_FNV1A, HMR_CLIENT_RELOAD_DELAY_MS, HMR_CLOSE_MESSAGE_TOO_LARGE, HMR_CLOSE_NORMAL, HMR_CLOSE_RATE_LIMIT, HMR_MAX_MESSAGE_SIZE_BYTES, HMR_MAX_MESSAGES_PER_MINUTE, HMR_RATE_LIMIT_WINDOW_MS, HTTP_BAD_REQUEST, HTTP_CONTENT_TYPE_IMAGE_GIF, HTTP_CONTENT_TYPE_IMAGE_ICO, HTTP_CONTENT_TYPE_IMAGE_JPEG, HTTP_CONTENT_TYPE_IMAGE_PNG, HTTP_CONTENT_TYPE_IMAGE_SVG, HTTP_CONTENT_TYPE_IMAGE_WEBP, HTTP_CONTENT_TYPES, HTTP_MODULE_FETCH_TIMEOUT_MS, HTTP_NETWORK_CONNECT_TIMEOUT, HTTP_NOT_FOUND, HTTP_NOT_IMPLEMENTED, HTTP_OK, HTTP_REDIRECT_FOUND, HTTP_SERVER_ERROR, HTTP_STATUS_CLIENT_ERROR_MIN, HTTP_STATUS_REDIRECT_MIN, HTTP_STATUS_SERVER_ERROR_MIN, HTTP_STATUS_SUCCESS_MIN, HTTP_UNAVAILABLE, IMAGE_OPTIMIZATION, MAX_BATCH_SIZE, MAX_PATH_LENGTH, MAX_PATH_TRAVERSAL_DEPTH, MS_PER_SECOND, PREFETCH_DEFAULT_DELAY_MS, PREFETCH_DEFAULT_TIMEOUT_MS, PREFETCH_MAX_SIZE_BYTES, REACT_DEFAULT_VERSION, RESPONSIVE_IMAGE_WIDTH_LG, RESPONSIVE_IMAGE_WIDTHS, RSC_MANIFEST_CACHE_TTL_MS, TSX_LAYOUT_MAX_ENTRIES, Z_INDEX_DEV_INDICATOR, Z_INDEX_ERROR_OVERLAY, } from "./constants/index.js";
|
|
10
10
|
export { VERSION } from "./version.js";
|
|
11
11
|
export { computeCodeHash, computeHash, fnv1aHash, shortHash, simpleHash, } from "./hash-utils.js";
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module utils/logger
|
|
5
5
|
*/
|
|
6
|
-
export { __registerRequestContextGetter, __registerTraceContextGetter, __resetLoggerConfigForTests, __resetTraceContextGetterForTests, agentLogger, bundlerLogger, cliLogger, createRequestLogger, getBaseLogger, getDefaultLevel, type LogEntry, type LogFormat, type Logger, logger, LogLevel, proxyLogger, rendererLogger, serverLogger, } from "./logger.js";
|
|
6
|
+
export { __registerRequestContextGetter, __registerTraceContextGetter, __resetLoggerConfigForTests, __resetTraceContextGetterForTests, agentLogger, bundlerLogger, cliLogger, createRequestLogger, getBaseLogger, getDefaultLevel, type LogEntry, type LogFormat, type Logger, logger, LogLevel, proxyLogger, refreshLoggerConfig, rendererLogger, serverLogger, } from "./logger.js";
|
|
7
7
|
export { ANSI, colorize, formatContextText, formatErrorText, formatTimestamp, formatValue, isRecord, LEVEL_COLORS, LEVEL_GLYPHS, type LogLevelName, normalizeText, padTag, PREFIX_WIDTH, type SerializedError, serializeError, TAG_WIDTH, truncateText, } from "./core.js";
|
|
8
8
|
export { getRequestContext, getRequestLogger, type RequestContext, requestContextStore, runWithRequestContext, runWithRequestContextAsync, } from "./request-context.js";
|
|
9
9
|
export { type LogComponent, LogComponents } from "./components.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/src/utils/logger/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,8BAA8B,EAC9B,4BAA4B,EAC5B,2BAA2B,EAC3B,iCAAiC,EACjC,WAAW,EACX,aAAa,EACb,SAAS,EACT,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,KAAK,QAAQ,EACb,KAAK,SAAS,EACd,KAAK,MAAM,EACX,MAAM,EACN,QAAQ,EACR,WAAW,EACX,cAAc,EACd,YAAY,GACb,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,IAAI,EACJ,QAAQ,EACR,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,WAAW,EACX,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,KAAK,YAAY,EACjB,aAAa,EACb,MAAM,EACN,YAAY,EACZ,KAAK,eAAe,EACpB,cAAc,EACd,SAAS,EACT,YAAY,GACb,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,cAAc,EACnB,mBAAmB,EACnB,qBAAqB,EACrB,0BAA0B,GAC3B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,KAAK,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/src/utils/logger/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACL,8BAA8B,EAC9B,4BAA4B,EAC5B,2BAA2B,EAC3B,iCAAiC,EACjC,WAAW,EACX,aAAa,EACb,SAAS,EACT,mBAAmB,EACnB,aAAa,EACb,eAAe,EACf,KAAK,QAAQ,EACb,KAAK,SAAS,EACd,KAAK,MAAM,EACX,MAAM,EACN,QAAQ,EACR,WAAW,EACX,mBAAmB,EACnB,cAAc,EACd,YAAY,GACb,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,IAAI,EACJ,QAAQ,EACR,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,WAAW,EACX,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,KAAK,YAAY,EACjB,aAAa,EACb,MAAM,EACN,YAAY,EACZ,KAAK,eAAe,EACpB,cAAc,EACd,SAAS,EACT,YAAY,GACb,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,cAAc,EACnB,mBAAmB,EACnB,qBAAqB,EACrB,0BAA0B,GAC3B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,KAAK,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module utils/logger
|
|
5
5
|
*/
|
|
6
|
-
export { __registerRequestContextGetter, __registerTraceContextGetter, __resetLoggerConfigForTests, __resetTraceContextGetterForTests, agentLogger, bundlerLogger, cliLogger, createRequestLogger, getBaseLogger, getDefaultLevel, logger, LogLevel, proxyLogger, rendererLogger, serverLogger, } from "./logger.js";
|
|
6
|
+
export { __registerRequestContextGetter, __registerTraceContextGetter, __resetLoggerConfigForTests, __resetTraceContextGetterForTests, agentLogger, bundlerLogger, cliLogger, createRequestLogger, getBaseLogger, getDefaultLevel, logger, LogLevel, proxyLogger, refreshLoggerConfig, rendererLogger, serverLogger, } from "./logger.js";
|
|
7
7
|
export { ANSI, colorize, formatContextText, formatErrorText, formatTimestamp, formatValue, isRecord, LEVEL_COLORS, LEVEL_GLYPHS, normalizeText, padTag, PREFIX_WIDTH, serializeError, TAG_WIDTH, truncateText, } from "./core.js";
|
|
8
8
|
export { getRequestContext, getRequestLogger, requestContextStore, runWithRequestContext, runWithRequestContextAsync, } from "./request-context.js";
|
|
9
9
|
export { LogComponents } from "./components.js";
|
|
@@ -59,11 +59,18 @@ export interface Logger {
|
|
|
59
59
|
component(name: string): Logger;
|
|
60
60
|
}
|
|
61
61
|
/**
|
|
62
|
-
*
|
|
63
|
-
*
|
|
62
|
+
* Determine the log level based on environment variables.
|
|
63
|
+
* Exported for testing purposes.
|
|
64
64
|
* @internal
|
|
65
65
|
*/
|
|
66
|
-
export declare function
|
|
66
|
+
export declare function getDefaultLevel(envLevel?: string | undefined, debugFlag?: string | undefined): LogLevel;
|
|
67
|
+
/**
|
|
68
|
+
* Re-read logger configuration from environment variables.
|
|
69
|
+
* Call after loading .env files so the logger picks up any overrides.
|
|
70
|
+
*/
|
|
71
|
+
export declare function refreshLoggerConfig(): void;
|
|
72
|
+
/** @internal Alias kept for tests. */
|
|
73
|
+
export declare const __resetLoggerConfigForTests: typeof refreshLoggerConfig;
|
|
67
74
|
declare class ConsoleLogger implements Logger {
|
|
68
75
|
private prefix;
|
|
69
76
|
private boundContext;
|
|
@@ -80,12 +87,6 @@ declare class ConsoleLogger implements Logger {
|
|
|
80
87
|
error(message: string, ...args: unknown[]): void;
|
|
81
88
|
time<T>(label: string, fn: () => Promise<T>): Promise<T>;
|
|
82
89
|
}
|
|
83
|
-
/**
|
|
84
|
-
* Determine the log level based on environment variables.
|
|
85
|
-
* Exported for testing purposes.
|
|
86
|
-
* @internal
|
|
87
|
-
*/
|
|
88
|
-
export declare function getDefaultLevel(envLevel?: string | undefined, debugFlag?: string | undefined): LogLevel;
|
|
89
90
|
/**
|
|
90
91
|
* Register the request context getter.
|
|
91
92
|
* Called by request-context.ts during module initialization.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../../src/src/utils/logger/logger.ts"],"names":[],"mappings":"AAIA,OAAO,EAOL,KAAK,YAAY,EAEjB,KAAK,eAAe,EAErB,MAAM,WAAW,CAAC;AAEnB,oBAAY,QAAQ;IAClB,KAAK,IAAI;IACT,IAAI,IAAI;IACR,IAAI,IAAI;IACR,KAAK,IAAI;CACV;AAED,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;AAExC;;;GAGG;AACH,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,YAAY,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAEhB,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAElC,KAAK,CAAC,EAAE,eAAe,CAAC;IAExB,mFAAmF;IACnF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iFAAiF;IACjF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gFAAgF;IAChF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qFAAqF;IACrF,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,oFAAoF;IACpF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,MAAM;IACrB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACjD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACjD,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACzD;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC;IAChD;;;;OAIG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;CACjC;
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../../src/src/utils/logger/logger.ts"],"names":[],"mappings":"AAIA,OAAO,EAOL,KAAK,YAAY,EAEjB,KAAK,eAAe,EAErB,MAAM,WAAW,CAAC;AAEnB,oBAAY,QAAQ;IAClB,KAAK,IAAI;IACT,IAAI,IAAI;IACR,IAAI,IAAI;IACR,KAAK,IAAI;CACV;AAED,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;AAExC;;;GAGG;AACH,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,YAAY,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAEhB,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAElC,KAAK,CAAC,EAAE,eAAe,CAAC;IAExB,mFAAmF;IACnF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iFAAiF;IACjF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gFAAgF;IAChF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qFAAqF;IACrF,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,oFAAoF;IACpF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,MAAM;IACrB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACjD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACjD,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACzD;;OAEG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC;IAChD;;;;OAIG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;CACjC;AAqBD;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,GAAE,MAAM,GAAG,SAA+B,EAClD,SAAS,GAAE,MAAM,GAAG,SAAqC,GACxD,QAAQ,CAKV;AA2BD;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAK1C;AAED,sCAAsC;AACtC,eAAO,MAAM,2BAA2B,4BAAsB,CAAC;AA6E/D,cAAM,aAAc,YAAW,MAAM;IAKjC,OAAO,CAAC,MAAM;IAJhB,OAAO,CAAC,YAAY,CAA0B;IAC9C,OAAO,CAAC,aAAa,CAAC,CAAS;gBAGrB,MAAM,EAAE,MAAM,EACtB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACtC,aAAa,CAAC,EAAE,MAAM;IAMxB,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM;IAI/C,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAI/B,OAAO,CAAC,UAAU;IAwDlB,OAAO,CAAC,cAAc;IAgBtB,OAAO,CAAC,GAAG;IAiBX,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAIhD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAI/C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAI/C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAI1C,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;CAa/D;AAsBD;;;;GAIG;AACH,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,MAAM;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,GAC3C,IAAI,CAEN;AASD;;;;GAIG;AACH,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,MAAM;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAClD,IAAI,CAEN;AAED;;;;GAIG;AACH,wBAAgB,iCAAiC,IAAI,IAAI,CAExD;AAsED,eAAO,MAAM,SAAS,QAA0C,CAAC;AACjE,eAAO,MAAM,YAAY,QAA6C,CAAC;AACvE,eAAO,MAAM,cAAc,QAA+C,CAAC;AAC3E,eAAO,MAAM,aAAa,QAA8C,CAAC;AACzE,eAAO,MAAM,WAAW,QAA4C,CAAC;AACrE,eAAO,MAAM,WAAW,QAA4C,CAAC;AACrE,eAAO,MAAM,MAAM,QAAuC,CAAC;AAE3D;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,CAiB3D;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,MAAM,EAClB,cAAc,EAAE;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GACA,MAAM,CAER"}
|
|
@@ -10,44 +10,30 @@ export var LogLevel;
|
|
|
10
10
|
LogLevel[LogLevel["WARN"] = 2] = "WARN";
|
|
11
11
|
LogLevel[LogLevel["ERROR"] = 3] = "ERROR";
|
|
12
12
|
})(LogLevel || (LogLevel = {}));
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
// ---- Config helpers (must be declared before the eager init below) ----
|
|
14
|
+
const LOG_LEVEL_MAP = {
|
|
15
|
+
DEBUG: LogLevel.DEBUG,
|
|
16
|
+
INFO: LogLevel.INFO,
|
|
17
|
+
WARN: LogLevel.WARN,
|
|
18
|
+
ERROR: LogLevel.ERROR,
|
|
19
|
+
};
|
|
20
|
+
function parseLogLevel(levelString) {
|
|
21
|
+
if (!levelString)
|
|
22
|
+
return undefined;
|
|
23
|
+
return LOG_LEVEL_MAP[levelString.toUpperCase()];
|
|
24
|
+
}
|
|
18
25
|
/**
|
|
19
|
-
*
|
|
20
|
-
*
|
|
26
|
+
* Determine the log level based on environment variables.
|
|
27
|
+
* Exported for testing purposes.
|
|
21
28
|
* @internal
|
|
22
29
|
*/
|
|
23
|
-
export function
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
function resolveLoggerConfig() {
|
|
31
|
-
const envLevel = getEnv("LOG_LEVEL");
|
|
32
|
-
const debugFlag = getEnv("VERYFRONT_DEBUG");
|
|
33
|
-
const envFormat = getEnv("LOG_FORMAT");
|
|
34
|
-
const envMode = getEnv("NODE_ENV");
|
|
35
|
-
if (cachedConfig &&
|
|
36
|
-
envLevel === cachedEnvLevel &&
|
|
37
|
-
debugFlag === cachedDebugFlag &&
|
|
38
|
-
envFormat === cachedEnvFormat &&
|
|
39
|
-
envMode === cachedEnvMode) {
|
|
40
|
-
return cachedConfig;
|
|
41
|
-
}
|
|
42
|
-
cachedEnvLevel = envLevel;
|
|
43
|
-
cachedDebugFlag = debugFlag;
|
|
44
|
-
cachedEnvFormat = envFormat;
|
|
45
|
-
cachedEnvMode = envMode;
|
|
46
|
-
cachedConfig = {
|
|
47
|
-
level: getDefaultLevel(envLevel, debugFlag),
|
|
48
|
-
format: getDefaultFormat(envFormat, envMode),
|
|
49
|
-
};
|
|
50
|
-
return cachedConfig;
|
|
30
|
+
export function getDefaultLevel(envLevel = getEnv("LOG_LEVEL"), debugFlag = getEnv("VERYFRONT_DEBUG")) {
|
|
31
|
+
const parsedLevel = parseLogLevel(envLevel);
|
|
32
|
+
if (parsedLevel !== undefined)
|
|
33
|
+
return parsedLevel;
|
|
34
|
+
if (debugFlag === "1" || debugFlag === "true")
|
|
35
|
+
return LogLevel.DEBUG;
|
|
36
|
+
return LogLevel.INFO;
|
|
51
37
|
}
|
|
52
38
|
/**
|
|
53
39
|
* Determine log format from environment.
|
|
@@ -58,6 +44,32 @@ function getDefaultFormat(envFormat = getEnv("LOG_FORMAT"), envMode = getEnv("NO
|
|
|
58
44
|
return envFormat;
|
|
59
45
|
return envMode === "production" ? "json" : "text";
|
|
60
46
|
}
|
|
47
|
+
// ---- Eager config resolution ----
|
|
48
|
+
/**
|
|
49
|
+
* Eagerly resolved at module load time so the config is captured from
|
|
50
|
+
* host process env vars BEFORE any per-request project env overlay is
|
|
51
|
+
* active. The project overlay blocks access to host env (for security),
|
|
52
|
+
* which would cause the logger to fall back to "text" format during SSR.
|
|
53
|
+
*/
|
|
54
|
+
let loggerConfig = {
|
|
55
|
+
level: getDefaultLevel(),
|
|
56
|
+
format: getDefaultFormat(),
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Re-read logger configuration from environment variables.
|
|
60
|
+
* Call after loading .env files so the logger picks up any overrides.
|
|
61
|
+
*/
|
|
62
|
+
export function refreshLoggerConfig() {
|
|
63
|
+
loggerConfig = {
|
|
64
|
+
level: getDefaultLevel(),
|
|
65
|
+
format: getDefaultFormat(),
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/** @internal Alias kept for tests. */
|
|
69
|
+
export const __resetLoggerConfigForTests = refreshLoggerConfig;
|
|
70
|
+
function resolveLoggerConfig() {
|
|
71
|
+
return loggerConfig;
|
|
72
|
+
}
|
|
61
73
|
/**
|
|
62
74
|
* Extract context from variadic args.
|
|
63
75
|
* First object argument becomes context, errors are handled specially.
|
|
@@ -238,30 +250,6 @@ class ConsoleLogger {
|
|
|
238
250
|
}
|
|
239
251
|
}
|
|
240
252
|
}
|
|
241
|
-
const LOG_LEVEL_MAP = {
|
|
242
|
-
DEBUG: LogLevel.DEBUG,
|
|
243
|
-
INFO: LogLevel.INFO,
|
|
244
|
-
WARN: LogLevel.WARN,
|
|
245
|
-
ERROR: LogLevel.ERROR,
|
|
246
|
-
};
|
|
247
|
-
function parseLogLevel(levelString) {
|
|
248
|
-
if (!levelString)
|
|
249
|
-
return undefined;
|
|
250
|
-
return LOG_LEVEL_MAP[levelString.toUpperCase()];
|
|
251
|
-
}
|
|
252
|
-
/**
|
|
253
|
-
* Determine the log level based on environment variables.
|
|
254
|
-
* Exported for testing purposes.
|
|
255
|
-
* @internal
|
|
256
|
-
*/
|
|
257
|
-
export function getDefaultLevel(envLevel = getEnv("LOG_LEVEL"), debugFlag = getEnv("VERYFRONT_DEBUG")) {
|
|
258
|
-
const parsedLevel = parseLogLevel(envLevel);
|
|
259
|
-
if (parsedLevel !== undefined)
|
|
260
|
-
return parsedLevel;
|
|
261
|
-
if (debugFlag === "1" || debugFlag === "true")
|
|
262
|
-
return LogLevel.DEBUG;
|
|
263
|
-
return LogLevel.INFO;
|
|
264
|
-
}
|
|
265
253
|
function createLogger(prefix) {
|
|
266
254
|
return new ConsoleLogger(prefix);
|
|
267
255
|
}
|
package/package.json
CHANGED
package/src/deno.js
CHANGED
|
@@ -622,7 +622,7 @@ export class ReadOperations {
|
|
|
622
622
|
cacheKey: string,
|
|
623
623
|
shouldCache: boolean,
|
|
624
624
|
): Promise<string> {
|
|
625
|
-
logger.
|
|
625
|
+
logger.debug("API_FETCH_START - fetching draft from API", {
|
|
626
626
|
path: normalizedPath,
|
|
627
627
|
apiPath,
|
|
628
628
|
cacheKey,
|
|
@@ -630,7 +630,7 @@ export class ReadOperations {
|
|
|
630
630
|
|
|
631
631
|
const content = await this.client.getFileContent(apiPath);
|
|
632
632
|
|
|
633
|
-
logger.
|
|
633
|
+
logger.debug("API_FETCH_DONE - got content from API", {
|
|
634
634
|
path: normalizedPath,
|
|
635
635
|
contentLength: content.length,
|
|
636
636
|
preview: previewText(content).replace(/\n/g, "\\n"),
|
|
@@ -116,7 +116,7 @@ export class WebSocketManager {
|
|
|
116
116
|
|
|
117
117
|
this.ws.onmessage = (event) => {
|
|
118
118
|
this.wsLastPong = Date.now();
|
|
119
|
-
logger.
|
|
119
|
+
logger.debug("WebSocket message received:", { data: event.data });
|
|
120
120
|
this.handlePokeMessage(event);
|
|
121
121
|
};
|
|
122
122
|
|
package/src/src/proxy/handler.ts
CHANGED
|
@@ -26,6 +26,7 @@ interface DomainLookupResult {
|
|
|
26
26
|
id: string;
|
|
27
27
|
slug: string;
|
|
28
28
|
name: string;
|
|
29
|
+
users?: Array<{ id: string }>;
|
|
29
30
|
environments?: Array<{
|
|
30
31
|
id: string;
|
|
31
32
|
name: string;
|
|
@@ -150,6 +151,30 @@ function extractUserToken(cookieHeader: string): string | undefined {
|
|
|
150
151
|
return match?.[1] ? decodeURIComponent(match[1]) : undefined;
|
|
151
152
|
}
|
|
152
153
|
|
|
154
|
+
function extractUserIdFromToken(token: string): string | undefined {
|
|
155
|
+
try {
|
|
156
|
+
const payload = token.split(".")[1];
|
|
157
|
+
if (!payload) return undefined;
|
|
158
|
+
// JWT payloads are base64url-encoded: normalize to standard base64 before decoding
|
|
159
|
+
let base64 = payload.replace(/-/g, "+").replace(/_/g, "/");
|
|
160
|
+
const remainder = base64.length % 4;
|
|
161
|
+
if (remainder === 2) base64 += "==";
|
|
162
|
+
else if (remainder === 3) base64 += "=";
|
|
163
|
+
const decoded = JSON.parse(atob(base64));
|
|
164
|
+
return decoded?.userId;
|
|
165
|
+
} catch {
|
|
166
|
+
return undefined;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function isProjectMember(
|
|
171
|
+
users: Array<{ id: string }> | undefined,
|
|
172
|
+
userId: string | undefined,
|
|
173
|
+
): boolean {
|
|
174
|
+
if (!users || !userId) return false;
|
|
175
|
+
return users.some((u) => u.id === userId);
|
|
176
|
+
}
|
|
177
|
+
|
|
153
178
|
export function createProxyHandler(options: ProxyHandlerOptions) {
|
|
154
179
|
const { config, cache, logger } = options;
|
|
155
180
|
const localProjects = config.localProjects ?? {};
|
|
@@ -249,6 +274,48 @@ export function createProxyHandler(options: ProxyHandlerOptions) {
|
|
|
249
274
|
return `https://veryfront.com/sign-in?from=${encodeURIComponent(returnPath)}`;
|
|
250
275
|
}
|
|
251
276
|
|
|
277
|
+
function checkProtectedAccess(
|
|
278
|
+
req: dntShim.Request,
|
|
279
|
+
matchingEnv: NonNullable<DomainLookupResult["environments"]>[number] | undefined,
|
|
280
|
+
userToken: string | undefined,
|
|
281
|
+
users: DomainLookupResult["users"],
|
|
282
|
+
logContext: Record<string, unknown>,
|
|
283
|
+
): { status: number; message: string; redirectUrl?: string } | null {
|
|
284
|
+
if (!matchingEnv?.protected) return null;
|
|
285
|
+
|
|
286
|
+
if (!userToken) {
|
|
287
|
+
const redirectUrl = makeAuthRedirectUrl(req);
|
|
288
|
+
logger?.info("Protected environment requires authentication", {
|
|
289
|
+
...logContext,
|
|
290
|
+
environmentName: matchingEnv.name,
|
|
291
|
+
redirectUrl,
|
|
292
|
+
});
|
|
293
|
+
return { status: 302, message: "Authentication required", redirectUrl };
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
const userId = extractUserIdFromToken(userToken);
|
|
297
|
+
if (!userId) {
|
|
298
|
+
// Malformed token — treat as unauthenticated so user can re-sign-in
|
|
299
|
+
const redirectUrl = makeAuthRedirectUrl(req);
|
|
300
|
+
logger?.info("Could not extract userId from token", {
|
|
301
|
+
...logContext,
|
|
302
|
+
environmentName: matchingEnv.name,
|
|
303
|
+
redirectUrl,
|
|
304
|
+
});
|
|
305
|
+
return { status: 302, message: "Authentication required", redirectUrl };
|
|
306
|
+
}
|
|
307
|
+
if (!isProjectMember(users, userId)) {
|
|
308
|
+
logger?.info("User is not a member of the project", {
|
|
309
|
+
...logContext,
|
|
310
|
+
environmentName: matchingEnv.name,
|
|
311
|
+
userId,
|
|
312
|
+
});
|
|
313
|
+
return { status: 403, message: "Access denied" };
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
return null;
|
|
317
|
+
}
|
|
318
|
+
|
|
252
319
|
async function resolveReleaseAndProtection(
|
|
253
320
|
req: dntShim.Request,
|
|
254
321
|
token: string,
|
|
@@ -265,15 +332,14 @@ export function createProxyHandler(options: ProxyHandlerOptions) {
|
|
|
265
332
|
|
|
266
333
|
const matchingEnv = lookupResult.environments?.find(envMatcher);
|
|
267
334
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
}
|
|
335
|
+
const protectionError = checkProtectedAccess(
|
|
336
|
+
req,
|
|
337
|
+
matchingEnv,
|
|
338
|
+
userToken,
|
|
339
|
+
lookupResult.users,
|
|
340
|
+
logContext,
|
|
341
|
+
);
|
|
342
|
+
if (protectionError) return { error: protectionError };
|
|
277
343
|
|
|
278
344
|
return {
|
|
279
345
|
projectId: lookupResult.id,
|
|
@@ -374,14 +440,21 @@ export function createProxyHandler(options: ProxyHandlerOptions) {
|
|
|
374
440
|
releaseId = matchingEnv?.active_release_id ?? undefined;
|
|
375
441
|
environmentId = matchingEnv?.id;
|
|
376
442
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
443
|
+
const protectionError = checkProtectedAccess(
|
|
444
|
+
req,
|
|
445
|
+
matchingEnv,
|
|
446
|
+
userToken,
|
|
447
|
+
lookupResult.users,
|
|
448
|
+
{ domain: host },
|
|
449
|
+
);
|
|
450
|
+
if (protectionError) {
|
|
451
|
+
return makeErrorContext(
|
|
452
|
+
base,
|
|
453
|
+
protectionError.status,
|
|
454
|
+
protectionError.message,
|
|
455
|
+
token,
|
|
456
|
+
protectionError.redirectUrl,
|
|
457
|
+
);
|
|
385
458
|
}
|
|
386
459
|
|
|
387
460
|
logger?.info("Resolved custom domain to project", {
|
|
@@ -11,7 +11,7 @@ import { enhanceAdapterWithFS } from "../platform/adapters/fs/integration.js";
|
|
|
11
11
|
import { isExtendedFSAdapter } from "../platform/adapters/fs/wrapper.js";
|
|
12
12
|
import { getEnv } from "../platform/compat/process.js";
|
|
13
13
|
import { initializeEsbuild } from "../platform/compat/esbuild.js";
|
|
14
|
-
import { logger } from "../utils/index.js";
|
|
14
|
+
import { logger, refreshLoggerConfig } from "../utils/index.js";
|
|
15
15
|
import { isDebugEnabled } from "../utils/constants/env.js";
|
|
16
16
|
import {
|
|
17
17
|
getEnvSource,
|
|
@@ -59,6 +59,7 @@ async function ensureEnvLoaded(projectDir: string, adapter: RuntimeAdapter): Pro
|
|
|
59
59
|
debug: isDebugEnabled(adapter.env),
|
|
60
60
|
});
|
|
61
61
|
refreshEnvironmentConfig();
|
|
62
|
+
refreshLoggerConfig();
|
|
62
63
|
} catch (error) {
|
|
63
64
|
bootstrapLog.warn("Failed to load .env files", {
|
|
64
65
|
error: getErrorMessage(error),
|
package/src/src/utils/index.ts
CHANGED
|
@@ -89,52 +89,33 @@ type LoggerConfig = {
|
|
|
89
89
|
format: LogFormat;
|
|
90
90
|
};
|
|
91
91
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
92
|
+
// ---- Config helpers (must be declared before the eager init below) ----
|
|
93
|
+
|
|
94
|
+
const LOG_LEVEL_MAP: Record<string, LogLevel> = {
|
|
95
|
+
DEBUG: LogLevel.DEBUG,
|
|
96
|
+
INFO: LogLevel.INFO,
|
|
97
|
+
WARN: LogLevel.WARN,
|
|
98
|
+
ERROR: LogLevel.ERROR,
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
function parseLogLevel(levelString: string | undefined): LogLevel | undefined {
|
|
102
|
+
if (!levelString) return undefined;
|
|
103
|
+
return LOG_LEVEL_MAP[levelString.toUpperCase()];
|
|
104
|
+
}
|
|
97
105
|
|
|
98
106
|
/**
|
|
99
|
-
*
|
|
100
|
-
*
|
|
107
|
+
* Determine the log level based on environment variables.
|
|
108
|
+
* Exported for testing purposes.
|
|
101
109
|
* @internal
|
|
102
110
|
*/
|
|
103
|
-
export function
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
function resolveLoggerConfig(): LoggerConfig {
|
|
112
|
-
const envLevel = getEnv("LOG_LEVEL");
|
|
113
|
-
const debugFlag = getEnv("VERYFRONT_DEBUG");
|
|
114
|
-
const envFormat = getEnv("LOG_FORMAT");
|
|
115
|
-
const envMode = getEnv("NODE_ENV");
|
|
116
|
-
|
|
117
|
-
if (
|
|
118
|
-
cachedConfig &&
|
|
119
|
-
envLevel === cachedEnvLevel &&
|
|
120
|
-
debugFlag === cachedDebugFlag &&
|
|
121
|
-
envFormat === cachedEnvFormat &&
|
|
122
|
-
envMode === cachedEnvMode
|
|
123
|
-
) {
|
|
124
|
-
return cachedConfig;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
cachedEnvLevel = envLevel;
|
|
128
|
-
cachedDebugFlag = debugFlag;
|
|
129
|
-
cachedEnvFormat = envFormat;
|
|
130
|
-
cachedEnvMode = envMode;
|
|
131
|
-
|
|
132
|
-
cachedConfig = {
|
|
133
|
-
level: getDefaultLevel(envLevel, debugFlag),
|
|
134
|
-
format: getDefaultFormat(envFormat, envMode),
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
return cachedConfig;
|
|
111
|
+
export function getDefaultLevel(
|
|
112
|
+
envLevel: string | undefined = getEnv("LOG_LEVEL"),
|
|
113
|
+
debugFlag: string | undefined = getEnv("VERYFRONT_DEBUG"),
|
|
114
|
+
): LogLevel {
|
|
115
|
+
const parsedLevel = parseLogLevel(envLevel);
|
|
116
|
+
if (parsedLevel !== undefined) return parsedLevel;
|
|
117
|
+
if (debugFlag === "1" || debugFlag === "true") return LogLevel.DEBUG;
|
|
118
|
+
return LogLevel.INFO;
|
|
138
119
|
}
|
|
139
120
|
|
|
140
121
|
/**
|
|
@@ -149,6 +130,37 @@ function getDefaultFormat(
|
|
|
149
130
|
return envMode === "production" ? "json" : "text";
|
|
150
131
|
}
|
|
151
132
|
|
|
133
|
+
// ---- Eager config resolution ----
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Eagerly resolved at module load time so the config is captured from
|
|
137
|
+
* host process env vars BEFORE any per-request project env overlay is
|
|
138
|
+
* active. The project overlay blocks access to host env (for security),
|
|
139
|
+
* which would cause the logger to fall back to "text" format during SSR.
|
|
140
|
+
*/
|
|
141
|
+
let loggerConfig: LoggerConfig = {
|
|
142
|
+
level: getDefaultLevel(),
|
|
143
|
+
format: getDefaultFormat(),
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Re-read logger configuration from environment variables.
|
|
148
|
+
* Call after loading .env files so the logger picks up any overrides.
|
|
149
|
+
*/
|
|
150
|
+
export function refreshLoggerConfig(): void {
|
|
151
|
+
loggerConfig = {
|
|
152
|
+
level: getDefaultLevel(),
|
|
153
|
+
format: getDefaultFormat(),
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/** @internal Alias kept for tests. */
|
|
158
|
+
export const __resetLoggerConfigForTests = refreshLoggerConfig;
|
|
159
|
+
|
|
160
|
+
function resolveLoggerConfig(): LoggerConfig {
|
|
161
|
+
return loggerConfig;
|
|
162
|
+
}
|
|
163
|
+
|
|
152
164
|
/**
|
|
153
165
|
* Extract context from variadic args.
|
|
154
166
|
* First object argument becomes context, errors are handled specially.
|
|
@@ -361,33 +373,6 @@ class ConsoleLogger implements Logger {
|
|
|
361
373
|
}
|
|
362
374
|
}
|
|
363
375
|
|
|
364
|
-
const LOG_LEVEL_MAP: Record<string, LogLevel> = {
|
|
365
|
-
DEBUG: LogLevel.DEBUG,
|
|
366
|
-
INFO: LogLevel.INFO,
|
|
367
|
-
WARN: LogLevel.WARN,
|
|
368
|
-
ERROR: LogLevel.ERROR,
|
|
369
|
-
};
|
|
370
|
-
|
|
371
|
-
function parseLogLevel(levelString: string | undefined): LogLevel | undefined {
|
|
372
|
-
if (!levelString) return undefined;
|
|
373
|
-
return LOG_LEVEL_MAP[levelString.toUpperCase()];
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
/**
|
|
377
|
-
* Determine the log level based on environment variables.
|
|
378
|
-
* Exported for testing purposes.
|
|
379
|
-
* @internal
|
|
380
|
-
*/
|
|
381
|
-
export function getDefaultLevel(
|
|
382
|
-
envLevel: string | undefined = getEnv("LOG_LEVEL"),
|
|
383
|
-
debugFlag: string | undefined = getEnv("VERYFRONT_DEBUG"),
|
|
384
|
-
): LogLevel {
|
|
385
|
-
const parsedLevel = parseLogLevel(envLevel);
|
|
386
|
-
if (parsedLevel !== undefined) return parsedLevel;
|
|
387
|
-
if (debugFlag === "1" || debugFlag === "true") return LogLevel.DEBUG;
|
|
388
|
-
return LogLevel.INFO;
|
|
389
|
-
}
|
|
390
|
-
|
|
391
376
|
function createLogger(prefix: string): ConsoleLogger {
|
|
392
377
|
return new ConsoleLogger(prefix);
|
|
393
378
|
}
|