veryfront 0.0.73 → 0.0.75

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/config.js CHANGED
@@ -65,6 +65,9 @@ var veryfrontConfigSchema = z.object({
65
65
  }).partial().optional(),
66
66
  router: z.enum(["app", "pages"]).optional(),
67
67
  defaultLayout: z.string().optional(),
68
+ layout: z.string().optional(),
69
+ provider: z.string().optional(),
70
+ app: z.string().optional(),
68
71
  theme: z.object({ colors: z.record(z.string()).optional() }).partial().optional(),
69
72
  build: z.object({
70
73
  outDir: z.string().optional(),
@@ -160,6 +163,8 @@ var veryfrontConfigSchema = z.object({
160
163
  apiBaseUrl: z.string().url(),
161
164
  apiToken: z.string(),
162
165
  projectSlug: z.string(),
166
+ proxyMode: z.boolean().optional(),
167
+ productionMode: z.boolean().optional(),
163
168
  cache: z.object({
164
169
  enabled: z.boolean().optional(),
165
170
  ttl: z.number().int().positive().optional(),
@@ -221,6 +226,9 @@ function findUnknownTopLevelKeys(input) {
221
226
  "experimental",
222
227
  "router",
223
228
  "defaultLayout",
229
+ "layout",
230
+ "provider",
231
+ "app",
224
232
  "theme",
225
233
  "build",
226
234
  "cache",
@@ -238,7 +246,7 @@ function findUnknownTopLevelKeys(input) {
238
246
  }
239
247
 
240
248
  // src/core/config/loader.ts
241
- import { join } from "node:path";
249
+ import { dirname, join } from "node:path";
242
250
 
243
251
  // src/core/utils/logger/logger.ts
244
252
  init_deno_env();
@@ -271,56 +279,158 @@ function getEnvironmentVariable(name) {
271
279
  }
272
280
  return void 0;
273
281
  }
282
+ function isProductionEnvironment() {
283
+ return getEnvironmentVariable("NODE_ENV") === "production";
284
+ }
274
285
 
275
286
  // src/core/utils/logger/logger.ts
276
287
  var cachedLogLevel;
288
+ var cachedLogFormat;
277
289
  function resolveLogLevel(force = false) {
278
290
  if (force || cachedLogLevel === void 0) {
279
291
  cachedLogLevel = getDefaultLevel();
280
292
  }
281
293
  return cachedLogLevel;
282
294
  }
283
- var ConsoleLogger = class {
284
- constructor(prefix, level = resolveLogLevel()) {
295
+ function resolveLogFormat(force = false) {
296
+ if (force || cachedLogFormat === void 0) {
297
+ cachedLogFormat = getDefaultFormat();
298
+ }
299
+ return cachedLogFormat;
300
+ }
301
+ function getDefaultFormat() {
302
+ const envFormat = getEnvironmentVariable("LOG_FORMAT");
303
+ if (envFormat === "json" || envFormat === "text") {
304
+ return envFormat;
305
+ }
306
+ return isProductionEnvironment() ? "json" : "text";
307
+ }
308
+ function serializeError(err) {
309
+ if (err instanceof Error) {
310
+ return {
311
+ name: err.name,
312
+ message: err.message,
313
+ stack: err.stack
314
+ };
315
+ }
316
+ if (err !== void 0 && err !== null) {
317
+ return {
318
+ name: "UnknownError",
319
+ message: String(err)
320
+ };
321
+ }
322
+ return void 0;
323
+ }
324
+ function extractContext(args) {
325
+ let context;
326
+ let error;
327
+ for (const arg of args) {
328
+ if (arg instanceof Error) {
329
+ error = serializeError(arg);
330
+ } else if (typeof arg === "object" && arg !== null && !Array.isArray(arg)) {
331
+ context = { ...context, ...arg };
332
+ }
333
+ }
334
+ return { context, error };
335
+ }
336
+ var ConsoleLogger = class _ConsoleLogger {
337
+ constructor(prefix, level = resolveLogLevel(), format = resolveLogFormat(), boundContext) {
285
338
  this.prefix = prefix;
286
339
  this.level = level;
340
+ this.format = format;
341
+ if (boundContext) {
342
+ this.boundContext = boundContext;
343
+ }
287
344
  }
345
+ boundContext = {};
288
346
  setLevel(level) {
289
347
  this.level = level;
290
348
  }
291
349
  getLevel() {
292
350
  return this.level;
293
351
  }
294
- debug(message, ...args) {
295
- if (this.level <= 0 /* DEBUG */) {
296
- console.debug(`[${this.prefix}] DEBUG: ${message}`, ...args);
352
+ setFormat(format) {
353
+ this.format = format;
354
+ }
355
+ getFormat() {
356
+ return this.format;
357
+ }
358
+ /**
359
+ * Create a child logger with additional bound context.
360
+ */
361
+ child(context) {
362
+ return new _ConsoleLogger(this.prefix, this.level, this.format, {
363
+ ...this.boundContext,
364
+ ...context
365
+ });
366
+ }
367
+ formatJson(level, message, args) {
368
+ const { context, error } = extractContext(args);
369
+ const entry = {
370
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
371
+ level,
372
+ service: this.prefix.toLowerCase(),
373
+ message
374
+ };
375
+ const mergedContext = { ...this.boundContext, ...context };
376
+ if (Object.keys(mergedContext).length > 0) {
377
+ if ("requestId" in mergedContext) {
378
+ entry.requestId = String(mergedContext.requestId);
379
+ delete mergedContext.requestId;
380
+ }
381
+ if ("traceId" in mergedContext) {
382
+ entry.traceId = String(mergedContext.traceId);
383
+ delete mergedContext.traceId;
384
+ }
385
+ if ("projectSlug" in mergedContext) {
386
+ entry.projectSlug = String(mergedContext.projectSlug);
387
+ delete mergedContext.projectSlug;
388
+ }
389
+ if ("durationMs" in mergedContext) {
390
+ entry.durationMs = Number(mergedContext.durationMs);
391
+ delete mergedContext.durationMs;
392
+ }
393
+ if (Object.keys(mergedContext).length > 0) {
394
+ entry.context = mergedContext;
395
+ }
297
396
  }
397
+ if (error) {
398
+ entry.error = error;
399
+ }
400
+ return JSON.stringify(entry);
298
401
  }
299
- info(message, ...args) {
300
- if (this.level <= 1 /* INFO */) {
301
- console.log(`[${this.prefix}] ${message}`, ...args);
402
+ log(level, logLevel, consoleFn, message, args) {
403
+ if (this.level > logLevel)
404
+ return;
405
+ if (this.format === "json") {
406
+ consoleFn(this.formatJson(level, message, args));
407
+ } else {
408
+ const prefix = level === "info" ? "" : ` ${level.toUpperCase()}:`;
409
+ consoleFn(`[${this.prefix}]${prefix} ${message}`, ...args);
302
410
  }
303
411
  }
412
+ debug(message, ...args) {
413
+ this.log("debug", 0 /* DEBUG */, console.debug, message, args);
414
+ }
415
+ info(message, ...args) {
416
+ this.log("info", 1 /* INFO */, console.log, message, args);
417
+ }
304
418
  warn(message, ...args) {
305
- if (this.level <= 2 /* WARN */) {
306
- console.warn(`[${this.prefix}] WARN: ${message}`, ...args);
307
- }
419
+ this.log("warn", 2 /* WARN */, console.warn, message, args);
308
420
  }
309
421
  error(message, ...args) {
310
- if (this.level <= 3 /* ERROR */) {
311
- console.error(`[${this.prefix}] ERROR: ${message}`, ...args);
312
- }
422
+ this.log("error", 3 /* ERROR */, console.error, message, args);
313
423
  }
314
424
  async time(label, fn) {
315
425
  const start = performance.now();
316
426
  try {
317
427
  const result = await fn();
318
- const end = performance.now();
319
- this.debug(`${label} completed in ${(end - start).toFixed(2)}ms`);
428
+ const durationMs = performance.now() - start;
429
+ this.debug(`${label} completed`, { durationMs: Math.round(durationMs) });
320
430
  return result;
321
431
  } catch (error) {
322
- const end = performance.now();
323
- this.error(`${label} failed after ${(end - start).toFixed(2)}ms`, error);
432
+ const durationMs = performance.now() - start;
433
+ this.error(`${label} failed`, { durationMs: Math.round(durationMs) }, error);
324
434
  throw error;
325
435
  }
326
436
  }
@@ -363,6 +473,7 @@ var serverLogger = createLogger("SERVER");
363
473
  var rendererLogger = createLogger("RENDERER");
364
474
  var bundlerLogger = createLogger("BUNDLER");
365
475
  var agentLogger = createLogger("AGENT");
476
+ var proxyLogger = createLogger("PROXY");
366
477
  var logger = createLogger("VERYFRONT");
367
478
 
368
479
  // src/core/utils/constants/cdn.ts
@@ -374,7 +485,7 @@ init_deno_env();
374
485
  // deno.json
375
486
  var deno_default = {
376
487
  name: "veryfront",
377
- version: "0.0.73",
488
+ version: "0.0.75",
378
489
  nodeModulesDir: "auto",
379
490
  exclude: [
380
491
  "npm/",
@@ -406,7 +517,11 @@ var deno_default = {
406
517
  "./oauth": "./src/core/oauth/index.ts",
407
518
  "./oauth/providers": "./src/core/oauth/providers/index.ts",
408
519
  "./oauth/handlers": "./src/core/oauth/handlers/index.ts",
409
- "./oauth/token-store": "./src/core/oauth/token-store/index.ts"
520
+ "./oauth/token-store": "./src/core/oauth/token-store/index.ts",
521
+ "./head": "./src/exports/head.ts",
522
+ "./router": "./src/exports/router.ts",
523
+ "./context": "./src/exports/context.ts",
524
+ "./fonts": "./src/exports/fonts.ts"
410
525
  },
411
526
  imports: {
412
527
  "@veryfront": "./src/index.ts",
@@ -459,12 +574,12 @@ var deno_default = {
459
574
  csstype: "https://esm.sh/csstype@3.2.3",
460
575
  "@types/react": "https://esm.sh/@types/react@18.3.27?deps=csstype@3.2.3",
461
576
  "@types/react-dom": "https://esm.sh/@types/react-dom@18.3.7?deps=csstype@3.2.3",
462
- react: "https://esm.sh/react@18.3.1",
463
- "react-dom": "https://esm.sh/react-dom@18.3.1",
464
- "react-dom/server": "https://esm.sh/react-dom@18.3.1/server",
465
- "react-dom/client": "https://esm.sh/react-dom@18.3.1/client",
466
- "react/jsx-runtime": "https://esm.sh/react@18.3.1/jsx-runtime",
467
- "react/jsx-dev-runtime": "https://esm.sh/react@18.3.1/jsx-dev-runtime",
577
+ react: "npm:react@18.3.1",
578
+ "react-dom": "npm:react-dom@18.3.1",
579
+ "react-dom/server": "npm:react-dom@18.3.1/server",
580
+ "react-dom/client": "npm:react-dom@18.3.1/client",
581
+ "react/jsx-runtime": "npm:react@18.3.1/jsx-runtime",
582
+ "react/jsx-dev-runtime": "npm:react@18.3.1/jsx-dev-runtime",
468
583
  "@mdx-js/mdx": "npm:@mdx-js/mdx@3.0.0",
469
584
  "@mdx-js/react": "npm:@mdx-js/react@3.0.0",
470
585
  "unist-util-visit": "npm:unist-util-visit@5.0.0",
@@ -474,27 +589,36 @@ var deno_default = {
474
589
  "remark-frontmatter": "npm:remark-frontmatter@5.0.0",
475
590
  "rehype-highlight": "npm:rehype-highlight@7.0.2",
476
591
  "rehype-slug": "npm:rehype-slug@6.0.0",
477
- esbuild: "https://deno.land/x/esbuild@v0.20.1/wasm.js",
478
- "esbuild/mod.js": "https://deno.land/x/esbuild@v0.20.1/mod.js",
592
+ esbuild: "npm:esbuild@0.20.2",
593
+ "esbuild/mod.js": "npm:esbuild@0.20.2",
479
594
  "es-module-lexer": "npm:es-module-lexer@1.5.0",
480
- zod: "npm:zod@3.23.8",
595
+ zod: "npm:zod@3.25.76",
481
596
  "mime-types": "npm:mime-types@2.1.35",
482
597
  mdast: "npm:@types/mdast@4.0.3",
483
598
  hast: "npm:@types/hast@3.0.3",
484
599
  unist: "npm:@types/unist@3.0.2",
485
600
  unified: "npm:unified@11.0.5",
486
- ai: "https://esm.sh/ai@5.0.76?deps=react@18.3.1,react-dom@18.3.1",
487
- "ai/react": "https://esm.sh/@ai-sdk/react@2.0.1?deps=react@18.3.1,react-dom@18.3.1",
488
- "@ai-sdk/react": "https://esm.sh/@ai-sdk/react@2.0.1?deps=react@18.3.1,react-dom@18.3.1",
601
+ ai: "npm:ai@5.0.76",
602
+ "ai/react": "npm:@ai-sdk/react@2.0.1",
603
+ "@ai-sdk/react": "npm:@ai-sdk/react@2.0.1",
489
604
  "@ai-sdk/openai": "https://esm.sh/@ai-sdk/openai@2.0.1",
490
605
  "@ai-sdk/anthropic": "https://esm.sh/@ai-sdk/anthropic@2.0.1",
491
606
  unocss: "https://esm.sh/unocss@0.59.0",
492
607
  "@unocss/core": "https://esm.sh/@unocss/core@0.59.0",
493
608
  "@unocss/preset-wind": "https://esm.sh/@unocss/preset-wind@0.59.0",
609
+ "next-themes": "npm:next-themes@0.4",
494
610
  redis: "npm:redis",
495
611
  pg: "npm:pg",
496
612
  "@opentelemetry/api": "npm:@opentelemetry/api@1",
497
- "@opentelemetry/core": "npm:@opentelemetry/core@1"
613
+ "@opentelemetry/core": "npm:@opentelemetry/core@1",
614
+ "@opentelemetry/sdk-trace-base": "npm:@opentelemetry/sdk-trace-base@1",
615
+ "@opentelemetry/exporter-trace-otlp-http": "npm:@opentelemetry/exporter-trace-otlp-http@0.57",
616
+ "@opentelemetry/resources": "npm:@opentelemetry/resources@1",
617
+ "@opentelemetry/semantic-conventions": "npm:@opentelemetry/semantic-conventions@1",
618
+ "@babel/parser": "npm:@babel/parser@7.26.3",
619
+ "@babel/traverse": "npm:@babel/traverse@7.26.3",
620
+ "@babel/generator": "npm:@babel/generator@7.26.3",
621
+ "@babel/types": "npm:@babel/types@7.26.3"
498
622
  },
499
623
  compilerOptions: {
500
624
  jsx: "react-jsx",
@@ -502,7 +626,7 @@ var deno_default = {
502
626
  strict: true,
503
627
  noImplicitAny: true,
504
628
  noUncheckedIndexedAccess: true,
505
- types: [],
629
+ types: ["npm:@types/react@18"],
506
630
  lib: [
507
631
  "deno.window",
508
632
  "dom",
@@ -517,9 +641,9 @@ var deno_default = {
517
641
  build: "deno compile --allow-all --output ../../bin/veryfront src/cli/main.ts",
518
642
  "build:npm": "deno run -A scripts/build-npm.ts",
519
643
  release: "deno run -A scripts/release.ts",
520
- test: "DENO_JOBS=1 deno test --parallel --fail-fast --allow-all --unstable-worker-options --unstable-net",
521
- "test:unit": "DENO_JOBS=1 deno test --parallel --allow-all --v8-flags=--max-old-space-size=8192 --ignore=tests --unstable-worker-options --unstable-net",
522
- "test:integration": "DENO_JOBS=1 deno test --parallel --fail-fast --allow-all tests --unstable-worker-options --unstable-net",
644
+ test: "VF_DISABLE_LRU_INTERVAL=1 DENO_JOBS=1 deno test --parallel --fail-fast --allow-all --unstable-worker-options --unstable-net",
645
+ "test:unit": "VF_DISABLE_LRU_INTERVAL=1 DENO_JOBS=1 deno test --parallel --allow-all --v8-flags=--max-old-space-size=8192 --ignore=tests,src/ai/workflow/__tests__ --unstable-worker-options --unstable-net",
646
+ "test:integration": "VF_DISABLE_LRU_INTERVAL=1 DENO_JOBS=1 deno test --parallel --fail-fast --allow-all tests --unstable-worker-options --unstable-net",
523
647
  "test:coverage": "rm -rf coverage && DENO_JOBS=1 deno test --parallel --fail-fast --allow-all --coverage=coverage --unstable-worker-options --unstable-net || exit 1",
524
648
  "test:coverage:unit": "rm -rf coverage && DENO_JOBS=1 deno test --parallel --fail-fast --allow-all --coverage=coverage --ignore=tests --unstable-worker-options --unstable-net || exit 1",
525
649
  "test:coverage:integration": "rm -rf coverage && DENO_JOBS=1 deno test --parallel --fail-fast --allow-all --coverage=coverage tests --unstable-worker-options --unstable-net || exit 1",
@@ -604,6 +728,7 @@ function getEnv(key) {
604
728
 
605
729
  // src/core/utils/version.ts
606
730
  var VERSION = getEnv("VERYFRONT_VERSION") || (typeof deno_default.version === "string" ? deno_default.version : "0.0.0");
731
+ var SERVER_START_TIME = Date.now();
607
732
 
608
733
  // src/core/utils/constants/cdn.ts
609
734
  var ESM_CDN_BASE = "https://esm.sh";
@@ -774,6 +899,165 @@ var DEV_SERVER_ENDPOINTS = {
774
899
  ERROR_OVERLAY: INTERNAL_ENDPOINTS.ERROR_OVERLAY
775
900
  };
776
901
 
902
+ // src/platform/compat/fs.ts
903
+ init_deno_env();
904
+ var NodeFileSystem = class {
905
+ fs = null;
906
+ os = null;
907
+ path = null;
908
+ initialized = false;
909
+ async ensureInitialized() {
910
+ if (this.initialized)
911
+ return;
912
+ if (!isNode) {
913
+ throw toError(createError({
914
+ type: "not_supported",
915
+ message: "Node.js fs modules not available",
916
+ feature: "Node.js"
917
+ }));
918
+ }
919
+ const [fsModule, osModule, pathModule] = await Promise.all([
920
+ import("node:fs/promises"),
921
+ import("node:os"),
922
+ import("node:path")
923
+ ]);
924
+ this.fs = fsModule;
925
+ this.os = osModule;
926
+ this.path = pathModule;
927
+ this.initialized = true;
928
+ }
929
+ async readTextFile(path) {
930
+ await this.ensureInitialized();
931
+ return await this.fs.readFile(path, { encoding: "utf8" });
932
+ }
933
+ async readFile(path) {
934
+ await this.ensureInitialized();
935
+ return await this.fs.readFile(path);
936
+ }
937
+ async writeTextFile(path, data) {
938
+ await this.ensureInitialized();
939
+ await this.fs.writeFile(path, data, { encoding: "utf8" });
940
+ }
941
+ async writeFile(path, data) {
942
+ await this.ensureInitialized();
943
+ await this.fs.writeFile(path, data);
944
+ }
945
+ async exists(path) {
946
+ await this.ensureInitialized();
947
+ try {
948
+ await this.fs.access(path);
949
+ return true;
950
+ } catch (error) {
951
+ if (error.code === "ENOENT") {
952
+ return false;
953
+ }
954
+ throw error;
955
+ }
956
+ }
957
+ async stat(path) {
958
+ await this.ensureInitialized();
959
+ const stat = await this.fs.stat(path);
960
+ return {
961
+ isFile: stat.isFile(),
962
+ isDirectory: stat.isDirectory(),
963
+ isSymlink: stat.isSymbolicLink(),
964
+ size: stat.size,
965
+ mtime: stat.mtime
966
+ };
967
+ }
968
+ async mkdir(path, options) {
969
+ await this.ensureInitialized();
970
+ await this.fs.mkdir(path, { recursive: options?.recursive ?? false });
971
+ }
972
+ async *readDir(path) {
973
+ await this.ensureInitialized();
974
+ const entries = await this.fs.readdir(path, { withFileTypes: true });
975
+ for (const entry of entries) {
976
+ yield {
977
+ name: entry.name,
978
+ isFile: entry.isFile(),
979
+ isDirectory: entry.isDirectory()
980
+ };
981
+ }
982
+ }
983
+ async remove(path, options) {
984
+ await this.ensureInitialized();
985
+ await this.fs.rm(path, {
986
+ recursive: options?.recursive ?? false,
987
+ force: options?.recursive ?? false
988
+ });
989
+ }
990
+ async makeTempDir(options) {
991
+ await this.ensureInitialized();
992
+ const tempDir = this.path.join(
993
+ this.os.tmpdir(),
994
+ `${options?.prefix ?? "tmp-"}${Math.random().toString(36).substring(2, 8)}`
995
+ );
996
+ await this.fs.mkdir(tempDir, { recursive: true });
997
+ return tempDir;
998
+ }
999
+ };
1000
+ var DenoFileSystem = class {
1001
+ async readTextFile(path) {
1002
+ return await Deno.readTextFile(path);
1003
+ }
1004
+ async readFile(path) {
1005
+ return await Deno.readFile(path);
1006
+ }
1007
+ async writeTextFile(path, data) {
1008
+ await Deno.writeTextFile(path, data);
1009
+ }
1010
+ async writeFile(path, data) {
1011
+ await Deno.writeFile(path, data);
1012
+ }
1013
+ async exists(path) {
1014
+ try {
1015
+ await Deno.stat(path);
1016
+ return true;
1017
+ } catch (error) {
1018
+ if (error instanceof Deno.errors.NotFound) {
1019
+ return false;
1020
+ }
1021
+ throw error;
1022
+ }
1023
+ }
1024
+ async stat(path) {
1025
+ const stat = await Deno.stat(path);
1026
+ return {
1027
+ isFile: stat.isFile,
1028
+ isDirectory: stat.isDirectory,
1029
+ isSymlink: stat.isSymlink,
1030
+ size: stat.size,
1031
+ mtime: stat.mtime
1032
+ };
1033
+ }
1034
+ async mkdir(path, options) {
1035
+ await Deno.mkdir(path, { recursive: options?.recursive ?? false });
1036
+ }
1037
+ async *readDir(path) {
1038
+ for await (const entry of Deno.readDir(path)) {
1039
+ yield {
1040
+ name: entry.name,
1041
+ isFile: entry.isFile,
1042
+ isDirectory: entry.isDirectory
1043
+ };
1044
+ }
1045
+ }
1046
+ async remove(path, options) {
1047
+ await Deno.remove(path, { recursive: options?.recursive ?? false });
1048
+ }
1049
+ async makeTempDir(options) {
1050
+ return await Deno.makeTempDir({ prefix: options?.prefix });
1051
+ }
1052
+ };
1053
+ function createFileSystem() {
1054
+ if (isDeno) {
1055
+ return new DenoFileSystem();
1056
+ } else {
1057
+ return new NodeFileSystem();
1058
+ }
1059
+ }
1060
+
777
1061
  // src/core/config/loader.ts
778
1062
  function getDefaultImportMapForConfig() {
779
1063
  return { imports: getReactImportMap(REACT_DEFAULT_VERSION) };
@@ -910,7 +1194,62 @@ var ConfigValidationError = class extends Error {
910
1194
  this.name = "ConfigValidationError";
911
1195
  }
912
1196
  };
913
- async function loadAndMergeConfig(configPath, projectDir) {
1197
+ function isVirtualFilesystem(adapter) {
1198
+ const wrappedAdapter = adapter?.fs?.fsAdapter;
1199
+ const adapterName = wrappedAdapter?.constructor?.name;
1200
+ return adapterName === "VeryfrontFSAdapter" || adapterName === "MultiProjectFSAdapter";
1201
+ }
1202
+ async function loadConfigFromVirtualFS(configPath, projectDir, adapter) {
1203
+ const fs = createFileSystem();
1204
+ const content = await adapter.fs.readFile(configPath);
1205
+ const source = typeof content === "string" ? content : new TextDecoder().decode(content);
1206
+ serverLogger.debug(`[CONFIG] Loading config from virtual FS: ${configPath}`);
1207
+ const isTsx = configPath.endsWith(".tsx");
1208
+ const loader = isTsx ? "tsx" : configPath.endsWith(".ts") ? "ts" : "js";
1209
+ const { build } = await import("esbuild");
1210
+ const result = await build({
1211
+ bundle: false,
1212
+ // Config files shouldn't need bundling
1213
+ write: false,
1214
+ format: "esm",
1215
+ platform: "neutral",
1216
+ target: "es2022",
1217
+ stdin: {
1218
+ contents: source,
1219
+ loader,
1220
+ resolveDir: dirname(configPath),
1221
+ sourcefile: configPath
1222
+ }
1223
+ });
1224
+ if (result.errors && result.errors.length > 0) {
1225
+ const first = result.errors[0]?.text || "unknown error";
1226
+ throw new ConfigValidationError(`Failed to transpile config: ${first}`);
1227
+ }
1228
+ const js = result.outputFiles?.[0]?.text ?? "export default {}";
1229
+ const tempDir = await fs.makeTempDir({ prefix: "vf-config-" });
1230
+ const tempFile = join(tempDir, "config.mjs");
1231
+ try {
1232
+ await fs.writeTextFile(tempFile, js);
1233
+ const configModule = await import(`file://${tempFile}?v=${Date.now()}`);
1234
+ const userConfig = configModule.default || configModule;
1235
+ if (userConfig === null || typeof userConfig !== "object" || Array.isArray(userConfig)) {
1236
+ throw new ConfigValidationError(
1237
+ `Expected object, received ${userConfig === null ? "null" : typeof userConfig}`
1238
+ );
1239
+ }
1240
+ validateCorsConfig(userConfig);
1241
+ validateConfigShape(userConfig);
1242
+ const merged = mergeConfigs(userConfig);
1243
+ configCacheByProject.set(projectDir, { revision: cacheRevision, config: merged });
1244
+ return merged;
1245
+ } finally {
1246
+ await fs.remove(tempDir, { recursive: true });
1247
+ }
1248
+ }
1249
+ async function loadAndMergeConfig(configPath, projectDir, adapter) {
1250
+ if (isVirtualFilesystem(adapter)) {
1251
+ return loadConfigFromVirtualFS(configPath, projectDir, adapter);
1252
+ }
914
1253
  try {
915
1254
  const configUrl = `file://${configPath}?t=${Date.now()}-${crypto.randomUUID()}`;
916
1255
  const configModule = await import(configUrl);
@@ -946,7 +1285,7 @@ async function getConfig(projectDir, adapter) {
946
1285
  if (!exists)
947
1286
  continue;
948
1287
  try {
949
- const merged = await loadAndMergeConfig(configPath, projectDir);
1288
+ const merged = await loadAndMergeConfig(configPath, projectDir, adapter);
950
1289
  if (merged)
951
1290
  return merged;
952
1291
  } catch (error) {