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