@timber-js/app 0.2.0-alpha.165 → 0.2.0-alpha.167

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.
Files changed (113) hide show
  1. package/dist/_chunks/{actions-CSDD6x7U.js → actions-TSxpXLHJ.js} +3 -3
  2. package/dist/_chunks/{actions-CSDD6x7U.js.map → actions-TSxpXLHJ.js.map} +1 -1
  3. package/dist/_chunks/{cache-api-eb1gydM7.js → cache-api-DzpQQOEx.js} +53 -49
  4. package/dist/_chunks/{cache-api-eb1gydM7.js.map → cache-api-DzpQQOEx.js.map} +1 -1
  5. package/dist/_chunks/{cli-schema-sync-mGfRbjh2.js → cli-schema-sync-wX-i90Og.js} +6 -4
  6. package/dist/_chunks/cli-schema-sync-wX-i90Og.js.map +1 -0
  7. package/dist/_chunks/cloudflare-AHoWYTYr.js +1188 -0
  8. package/dist/_chunks/cloudflare-AHoWYTYr.js.map +1 -0
  9. package/dist/_chunks/{define-CFmvb4Bt.js → define-COtkxMRT.js} +16 -28
  10. package/dist/_chunks/define-COtkxMRT.js.map +1 -0
  11. package/dist/_chunks/{define-Bssfp6ot.js → define-c4au4I9R.js} +2 -2
  12. package/dist/_chunks/{define-Bssfp6ot.js.map → define-c4au4I9R.js.map} +1 -1
  13. package/dist/_chunks/{logger-B_O6-mdJ.js → logger-t3uxAmbX.js} +3 -3
  14. package/dist/_chunks/logger-t3uxAmbX.js.map +1 -0
  15. package/dist/_chunks/{plugin-context-BnaiU_cF.js → plugin-context---kTF5v8.js} +2 -2
  16. package/dist/_chunks/{plugin-context-BnaiU_cF.js.map → plugin-context---kTF5v8.js.map} +1 -1
  17. package/dist/_chunks/{resolve-schema-3iUvBV5T.js → resolve-schema-Dz3fcFUo.js} +2 -2
  18. package/dist/_chunks/{resolve-schema-3iUvBV5T.js.map → resolve-schema-Dz3fcFUo.js.map} +1 -1
  19. package/dist/_chunks/{schema-bridge-BY3QLBL7.js → schema-bridge-DT_Tn0Xf.js} +2 -2
  20. package/dist/_chunks/{schema-bridge-BY3QLBL7.js.map → schema-bridge-DT_Tn0Xf.js.map} +1 -1
  21. package/dist/_chunks/{use-query-states-CbeQmext.js → use-query-states-DFvWd-EA.js} +65 -7
  22. package/dist/_chunks/use-query-states-DFvWd-EA.js.map +1 -0
  23. package/dist/_chunks/{walkers-BL3MCMgO.js → walkers-Cfwvl-UC.js} +3 -3
  24. package/dist/_chunks/{walkers-BL3MCMgO.js.map → walkers-Cfwvl-UC.js.map} +1 -1
  25. package/dist/adapters/cloudflare-dev.js +1 -1
  26. package/dist/adapters/cloudflare-kv-cache.js +1 -1
  27. package/dist/adapters/cloudflare.d.ts +12 -1
  28. package/dist/adapters/cloudflare.d.ts.map +1 -1
  29. package/dist/adapters/cloudflare.js +2 -461
  30. package/dist/adapters/nitro.js +1 -1
  31. package/dist/adapters/types.d.ts +2 -0
  32. package/dist/adapters/types.d.ts.map +1 -1
  33. package/dist/cache/cache-api.d.ts +33 -11
  34. package/dist/cache/cache-api.d.ts.map +1 -1
  35. package/dist/cache/index.js +1 -1
  36. package/dist/cli.js +2 -2
  37. package/dist/client/browser-entry/post-hydration.d.ts.map +1 -1
  38. package/dist/client/history.d.ts +10 -0
  39. package/dist/client/history.d.ts.map +1 -1
  40. package/dist/client/internal.js +139 -115
  41. package/dist/client/internal.js.map +1 -1
  42. package/dist/client/router.d.ts.map +1 -1
  43. package/dist/client/use-query-states.d.ts.map +1 -1
  44. package/dist/codec.js +1 -1
  45. package/dist/cookies/index.js +1 -1
  46. package/dist/dev-tools/logs.d.ts +15 -1
  47. package/dist/dev-tools/logs.d.ts.map +1 -1
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +138 -45
  50. package/dist/index.js.map +1 -1
  51. package/dist/params/index.js +1 -1
  52. package/dist/plugins/adapter-build.d.ts.map +1 -1
  53. package/dist/plugins/cache.d.ts +8 -8
  54. package/dist/plugins/cache.d.ts.map +1 -1
  55. package/dist/routing/index.js +2 -2
  56. package/dist/schema-bridge.d.ts.map +1 -1
  57. package/dist/search-params/define.d.ts +35 -4
  58. package/dist/search-params/define.d.ts.map +1 -1
  59. package/dist/search-params/index.js +3 -7
  60. package/dist/search-params/index.js.map +1 -1
  61. package/dist/search-params/wrappers.d.ts +2 -2
  62. package/dist/search-params/wrappers.d.ts.map +1 -1
  63. package/dist/segment-params/index.js +1 -1
  64. package/dist/server/als-registry.d.ts +7 -0
  65. package/dist/server/als-registry.d.ts.map +1 -1
  66. package/dist/server/deny-boundary.d.ts +3 -1
  67. package/dist/server/deny-boundary.d.ts.map +1 -1
  68. package/dist/server/index.js +2 -2
  69. package/dist/server/internal.js +12 -7
  70. package/dist/server/internal.js.map +1 -1
  71. package/dist/server/route-element-builder.d.ts +9 -0
  72. package/dist/server/route-element-builder.d.ts.map +1 -1
  73. package/dist/server/rsc-entry/render-route.d.ts.map +1 -1
  74. package/dist/server/rsc-entry/rsc-payload.d.ts.map +1 -1
  75. package/dist/server/rsc-entry/rsc-stream.d.ts +8 -0
  76. package/dist/server/rsc-entry/rsc-stream.d.ts.map +1 -1
  77. package/dist/server/stream-utils.d.ts.map +1 -1
  78. package/docs/api/32-api-cache.mdx +4 -4
  79. package/docs/api/33-api-search-params.mdx +13 -0
  80. package/docs/learn/00-introduction.mdx +1 -2
  81. package/docs/learn/09-caching.mdx +5 -5
  82. package/docs/more/03-coming-from-nextjs.mdx +2 -2
  83. package/docs/more/50-ai-agent-instructions.mdx +5 -5
  84. package/package.json +10 -8
  85. package/src/adapters/cloudflare.ts +63 -25
  86. package/src/adapters/types.ts +2 -0
  87. package/src/cache/cache-api.ts +84 -84
  88. package/src/cli.ts +0 -0
  89. package/src/client/browser-entry/post-hydration.ts +16 -9
  90. package/src/client/history.ts +11 -0
  91. package/src/client/router.ts +212 -206
  92. package/src/client/use-query-states.ts +99 -7
  93. package/src/dev-tools/logs.ts +119 -34
  94. package/src/index.ts +14 -1
  95. package/src/plugins/adapter-build.ts +1 -0
  96. package/src/plugins/cache.ts +45 -30
  97. package/src/routing/scanner.ts +7 -0
  98. package/src/schema-bridge.ts +4 -3
  99. package/src/search-params/define.ts +57 -51
  100. package/src/search-params/wrappers.ts +17 -26
  101. package/src/server/als-registry.ts +7 -0
  102. package/src/server/deny-boundary.ts +6 -3
  103. package/src/server/route-element-builder.ts +49 -8
  104. package/src/server/rsc-entry/render-route.ts +3 -1
  105. package/src/server/rsc-entry/rsc-payload.ts +21 -4
  106. package/src/server/rsc-entry/rsc-stream.ts +8 -0
  107. package/src/server/stream-utils.ts +8 -6
  108. package/LICENSE +0 -8
  109. package/dist/_chunks/cli-schema-sync-mGfRbjh2.js.map +0 -1
  110. package/dist/_chunks/define-CFmvb4Bt.js.map +0 -1
  111. package/dist/_chunks/logger-B_O6-mdJ.js.map +0 -1
  112. package/dist/_chunks/use-query-states-CbeQmext.js.map +0 -1
  113. package/dist/adapters/cloudflare.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,12 +1,13 @@
1
1
  import { a as __esmMin, o as __exportAll, s as __toCommonJS } from "./_chunks/dist-BA3u1z3W.js";
2
2
  import { c as isDynamicMetadataExtension, l as isMetadataRouteServePath, r as canonicalize } from "./_chunks/canonicalize-P41GR6tY.js";
3
3
  import { t as matchUrlParts } from "./_chunks/tree-match-D2l830j2.js";
4
- import { h as swallow } from "./_chunks/logger-B_O6-mdJ.js";
5
- import { i as scanRoutes } from "./_chunks/cli-schema-sync-mGfRbjh2.js";
6
- import { a as generateRouteMap, c as fileHasDirective, d as getPrerenderExport, i as validateSchemaAgainstRoutes, l as fileHasExport, n as collectInterceptionRewrites, o as fileHasAnyExport, s as fileHasDefaultExport, t as collectLeafRoutes, u as fileHasStarExport } from "./_chunks/walkers-BL3MCMgO.js";
7
- import { a as resolveAppDir, c as createNoopTimer, n as loadTimberConfigFile, o as resolveBuildDir, r as mergeFileConfig, s as resolveClientJavascript, t as createPluginContext } from "./_chunks/plugin-context-BnaiU_cF.js";
4
+ import { h as swallow } from "./_chunks/logger-t3uxAmbX.js";
5
+ import { i as scanRoutes } from "./_chunks/cli-schema-sync-wX-i90Og.js";
6
+ import { a as generateRouteMap, c as fileHasDirective, d as getPrerenderExport, i as validateSchemaAgainstRoutes, l as fileHasExport, n as collectInterceptionRewrites, o as fileHasAnyExport, s as fileHasDefaultExport, t as collectLeafRoutes, u as fileHasStarExport } from "./_chunks/walkers-Cfwvl-UC.js";
7
+ import { a as resolveAppDir, c as createNoopTimer, n as loadTimberConfigFile, o as resolveBuildDir, r as mergeFileConfig, s as resolveClientJavascript, t as createPluginContext } from "./_chunks/plugin-context---kTF5v8.js";
8
8
  import { t as fnv1aHash } from "./_chunks/fast-hash-D6hIVt1Y.js";
9
9
  import { t as formatSize } from "./_chunks/format-CfwjgPz9.js";
10
+ import { createLogger, parseAst } from "vite";
10
11
  import { basename, dirname, extname, join, normalize, relative, resolve, win32 } from "node:path";
11
12
  import { builtinModules, createRequire } from "node:module";
12
13
  import react, { reactCompilerPreset } from "@vitejs/plugin-react";
@@ -21,7 +22,6 @@ import { styleText } from "node:util";
21
22
  import { constants, createGzip, gzipSync } from "node:zlib";
22
23
  import { copyFile, mkdir, readFile, rename, rm, stat, writeFile } from "node:fs/promises";
23
24
  import { createHash, randomUUID } from "node:crypto";
24
- import { parseAst } from "vite";
25
25
  //#region src/plugins/content.ts
26
26
  var CONFIG_FILE_NAMES$1 = [
27
27
  "content-collections.ts",
@@ -6453,6 +6453,76 @@ function timberBuildManifest(ctx) {
6453
6453
  }
6454
6454
  //#endregion
6455
6455
  //#region src/dev-tools/logs.ts
6456
+ /**
6457
+ * Snapshot of the original console methods, captured at module load time
6458
+ * (before any patching). Used as Vite's `customLogger` console so that
6459
+ * forwardConsole output bypasses our patch entirely — eliminating the
6460
+ * server→browser→server forwarding loop without string matching.
6461
+ */
6462
+ var originalConsole = {
6463
+ log: console.log.bind(console),
6464
+ warn: console.warn.bind(console),
6465
+ error: console.error.bind(console),
6466
+ debug: console.debug.bind(console),
6467
+ info: console.info.bind(console)
6468
+ };
6469
+ /**
6470
+ * Wrap a Vite Logger so its output methods route through `originalConsole`
6471
+ * instead of the global (potentially patched) console. This prevents the
6472
+ * server→browser→server forwarding loop even when the user supplies their
6473
+ * own `customLogger` that internally calls console methods.
6474
+ */
6475
+ function wrapLoggerWithOriginalConsole(logger) {
6476
+ function withOriginals(fn) {
6477
+ const saved = {
6478
+ log: console.log,
6479
+ warn: console.warn,
6480
+ error: console.error,
6481
+ debug: console.debug,
6482
+ info: console.info
6483
+ };
6484
+ console.log = originalConsole.log;
6485
+ console.warn = originalConsole.warn;
6486
+ console.error = originalConsole.error;
6487
+ console.debug = originalConsole.debug;
6488
+ console.info = originalConsole.info;
6489
+ try {
6490
+ return fn();
6491
+ } finally {
6492
+ console.log = saved.log;
6493
+ console.warn = saved.warn;
6494
+ console.error = saved.error;
6495
+ console.debug = saved.debug;
6496
+ console.info = saved.info;
6497
+ }
6498
+ }
6499
+ return {
6500
+ get hasWarned() {
6501
+ return logger.hasWarned;
6502
+ },
6503
+ set hasWarned(v) {
6504
+ logger.hasWarned = v;
6505
+ },
6506
+ info(msg, opts) {
6507
+ withOriginals(() => logger.info(msg, opts));
6508
+ },
6509
+ warn(msg, opts) {
6510
+ withOriginals(() => logger.warn(msg, opts));
6511
+ },
6512
+ warnOnce(msg, opts) {
6513
+ withOriginals(() => logger.warnOnce(msg, opts));
6514
+ },
6515
+ error(msg, opts) {
6516
+ withOriginals(() => logger.error(msg, opts));
6517
+ },
6518
+ clearScreen(type) {
6519
+ logger.clearScreen(type);
6520
+ },
6521
+ hasErrorLogged(error) {
6522
+ return logger.hasErrorLogged(error);
6523
+ }
6524
+ };
6525
+ }
6456
6526
  var LOG_LEVELS = [
6457
6527
  "log",
6458
6528
  "warn",
@@ -6575,28 +6645,37 @@ function isFrameworkInternalCaller() {
6575
6645
  * 3. Sends via server.hot.send() — dropped if no clients connected
6576
6646
  */
6577
6647
  function patchConsole(server, projectRoot) {
6578
- const originals = /* @__PURE__ */ new Map();
6648
+ const prevConsole = /* @__PURE__ */ new Map();
6649
+ const patchingLevel = /* @__PURE__ */ new Set();
6579
6650
  for (const level of LOG_LEVELS) {
6580
- originals.set(level, console[level].bind(console));
6651
+ prevConsole.set(level, console[level].bind(console));
6581
6652
  console[level] = (...args) => {
6582
- originals.get(level)(...args);
6583
- if (isFrameworkInternalCaller()) return;
6584
- if (typeof args[0] === "string" && args[0].includes("[console.")) return;
6653
+ if (patchingLevel.has(level)) {
6654
+ prevConsole.get(level)(...args);
6655
+ return;
6656
+ }
6657
+ patchingLevel.add(level);
6585
6658
  try {
6586
- const payload = {
6587
- level,
6588
- args: args.map((arg) => serializeArg(arg)),
6589
- location: extractCallerLocation(projectRoot),
6590
- timestamp: Date.now()
6591
- };
6592
- server.hot.send("timber:server-log", payload);
6593
- } catch (e) {
6594
- originals.get("debug")("[timber] server log forwarding failed:", e instanceof Error ? e.message : e);
6659
+ prevConsole.get(level)(...args);
6660
+ if (isFrameworkInternalCaller()) return;
6661
+ try {
6662
+ const payload = {
6663
+ level,
6664
+ args: args.map((arg) => serializeArg(arg)),
6665
+ location: extractCallerLocation(projectRoot),
6666
+ timestamp: Date.now()
6667
+ };
6668
+ server.hot.send("timber:server-log", payload);
6669
+ } catch (e) {
6670
+ originalConsole.debug("[timber] server log forwarding failed:", e instanceof Error ? e.message : e);
6671
+ }
6672
+ } finally {
6673
+ patchingLevel.delete(level);
6595
6674
  }
6596
6675
  };
6597
6676
  }
6598
6677
  return () => {
6599
- for (const [level, original] of originals) console[level] = original;
6678
+ for (const [level, prev] of prevConsole) console[level] = prev;
6600
6679
  };
6601
6680
  }
6602
6681
  /**
@@ -7304,14 +7383,14 @@ function generateStableCallsiteId(relativeModulePath, kind, statementText, callS
7304
7383
  //#region src/plugins/cache.ts
7305
7384
  /**
7306
7385
  * timber-cache-transform — Vite plugin that injects stable callsite IDs
7307
- * into `cache()` calls imported from `@timber-js/app/cache`.
7386
+ * into `cache.data()` calls imported from `@timber-js/app/cache`.
7308
7387
  *
7309
7388
  * Detected callsite forms (TIM-1054):
7310
- * - named imports, including aliases: `import { cache as c }` + `c(fn, opts)`
7311
- * - namespace imports: `import * as ns` + `ns.cache(fn, opts)`
7389
+ * - named imports, including aliases: `import { cache as c }` + `c.data(fn, opts)`
7390
+ * - namespace imports: `import * as ns` + `ns.cache.data(fn, opts)`
7312
7391
  * Forms a per-module transform cannot trace — local variable aliases
7313
7392
  * (`const c = cache`), user re-export wrapper modules, computed access
7314
- * (`ns['cache']`) — fall back to the runtime fnId derived from
7393
+ * (`cache['data']`) — fall back to the runtime fnId derived from
7315
7394
  * fnv1a(fn.toString()) (see cache/timber-cache.ts), which is deterministic
7316
7395
  * across instances and cold starts of the same build. Without either
7317
7396
  * mechanism, an ordinal counter would collide across instances with a shared
@@ -7319,8 +7398,8 @@ function generateStableCallsiteId(relativeModulePath, kind, statementText, callS
7319
7398
  * data to another.
7320
7399
  *
7321
7400
  * The plugin transforms:
7322
- * cache(fn, opts) → cache(fn, opts, "stable-id")
7323
- * ns.cache(fn, opts) → ns.cache(fn, opts, "stable-id")
7401
+ * cache.data(fn, opts) → cache.data(fn, opts, "stable-id")
7402
+ * ns.cache.data(fn, opts) → ns.cache.data(fn, opts, "stable-id")
7324
7403
  *
7325
7404
  * where stable-id =
7326
7405
  * fnv1a(relPath + ":cache:" + fnv1a(stmtText) + ":" + fnv1a(callSpanText) + ":" + occurrence)
@@ -7338,9 +7417,9 @@ function generateStableCallsiteId(relativeModulePath, kind, statementText, callS
7338
7417
  * unrelated edits, while a changed call gets a fresh ID — which is exactly
7339
7418
  * when invalidation is wanted.
7340
7419
  *
7341
- * The enclosing-statement text is included so that byte-identical cache()
7420
+ * The enclosing-statement text is included so that byte-identical cache.data()
7342
7421
  * calls in different scopes — e.g. two factory helpers that each `return
7343
- * cache(fn, { ttl: 60 })` — get distinct, insertion-stable IDs: their
7422
+ * cache.data(fn, { ttl: 60 })` — get distinct, insertion-stable IDs: their
7344
7423
  * enclosing declarations differ by name/body even when the call spans are
7345
7424
  * identical. Without it, a source-order occurrence counter alone would shift
7346
7425
  * when an identical span is inserted above, reassigning IDs across deploys.
@@ -7357,32 +7436,40 @@ function generateStableCallsiteId(relativeModulePath, kind, statementText, callS
7357
7436
  * See TIM-997, TIM-1053, design/06-caching.md §"Cache Key Security".
7358
7437
  */
7359
7438
  /**
7360
- * Is this callee a reference to the imported `cache` function — either a bare
7361
- * identifier bound by a named import, or `ns.cache` on a namespace import?
7362
- * Computed access (`ns['cache']`) is deliberately not matched; it falls back
7439
+ * Is this callee a `cache.data(...)` call? Matches two forms:
7440
+ * - Named import: `cache.data(fn, opts)` where `cache` is the imported binding
7441
+ * - Namespace import: `ns.cache.data(fn, opts)` where `ns` is the namespace
7442
+ * Computed access (`cache['data']`) is deliberately not matched; it falls back
7363
7443
  * to the runtime fnId derivation.
7364
7444
  */
7365
- function isCacheCallee(callee, bindings) {
7366
- if (callee.type === "Identifier") return bindings.named.has(callee.name);
7367
- if (callee.type === "MemberExpression") {
7368
- const member = callee;
7369
- return !member.computed && member.object.type === "Identifier" && bindings.namespaces.has(member.object.name) && member.property.type === "Identifier" && member.property.name === "cache";
7445
+ function isCacheDataCallee(callee, bindings) {
7446
+ if (callee.type !== "MemberExpression") return false;
7447
+ const member = callee;
7448
+ if (member.computed) return false;
7449
+ if (member.property.type !== "Identifier" || member.property.name !== "data") return false;
7450
+ const obj = member.object;
7451
+ if (obj.type === "Identifier") return bindings.named.has(obj.name);
7452
+ if (obj.type === "MemberExpression") {
7453
+ const outer = obj;
7454
+ return !outer.computed && outer.object.type === "Identifier" && bindings.namespaces.has(outer.object.name) && outer.property.type === "Identifier" && outer.property.name === "cache";
7370
7455
  }
7371
7456
  return false;
7372
7457
  }
7373
7458
  /**
7374
- * Extract the local binding name that a cache callee resolves to — the
7375
- * identifier for named imports, or the namespace object for `ns.cache()`.
7459
+ * Extract the local binding name that a cache.data callee resolves to — the
7460
+ * `cache` identifier for named imports, or the namespace object for `ns.cache.data()`.
7376
7461
  */
7377
7462
  function calleeBindingName(callee, bindings) {
7378
- if (callee.type === "Identifier") {
7379
- const name = callee.name;
7463
+ if (callee.type !== "MemberExpression") return null;
7464
+ const obj = callee.object;
7465
+ if (obj.type === "Identifier") {
7466
+ const name = obj.name;
7380
7467
  return bindings.named.has(name) ? name : null;
7381
7468
  }
7382
- if (callee.type === "MemberExpression") {
7383
- const member = callee;
7384
- if (member.object.type === "Identifier") {
7385
- const name = member.object.name;
7469
+ if (obj.type === "MemberExpression") {
7470
+ const outer = obj;
7471
+ if (outer.object.type === "Identifier") {
7472
+ const name = outer.object.name;
7386
7473
  return bindings.namespaces.has(name) ? name : null;
7387
7474
  }
7388
7475
  }
@@ -7420,7 +7507,7 @@ function timberCacheTransform(ctx) {
7420
7507
  const callSites = [];
7421
7508
  for (const stmt of program.body) {
7422
7509
  const calls = [];
7423
- findCallSites(stmt, (call) => call.arguments.length === 2 && isCacheCallee(call.callee, cacheBindings) && !isCalleeShadowed(call), calls);
7510
+ findCallSites(stmt, (call) => call.arguments.length === 2 && isCacheDataCallee(call.callee, cacheBindings) && !isCalleeShadowed(call), calls);
7424
7511
  for (const call of calls) callSites.push({
7425
7512
  call,
7426
7513
  stmt
@@ -8571,6 +8658,7 @@ function timberAdapterBuild(ctx) {
8571
8658
  }
8572
8659
  if (ctx.clientJavascript.disabled) await stripJsFromRscAssetsManifests(buildDir);
8573
8660
  const adapterConfig = {
8661
+ root: ctx.root,
8574
8662
  output: ctx.config.output ?? "server",
8575
8663
  clientJavascriptDisabled: ctx.clientJavascript.disabled,
8576
8664
  manifestInit
@@ -9545,10 +9633,15 @@ function timber(config) {
9545
9633
  previewConfig.strictPort = resolvedDevPortExplicit;
9546
9634
  }
9547
9635
  serverConfig.forwardConsole = resolveForwardConsole(ctx.config.devBrowserLogs);
9636
+ const customLogger = userConfig.customLogger ? wrapLoggerWithOriginalConsole(userConfig.customLogger) : createLogger(userConfig.logLevel ?? "info", {
9637
+ allowClearScreen: userConfig.clearScreen ?? true,
9638
+ console: originalConsole
9639
+ });
9548
9640
  return {
9549
9641
  build: { outDir: buildOutDir },
9550
9642
  environments: envOutDirs,
9551
9643
  optimizeDeps: { exclude: timberOptimizeDepsExclude },
9644
+ customLogger,
9552
9645
  server: serverConfig,
9553
9646
  preview: previewConfig
9554
9647
  };