@farm.js/core 0.1.15 → 0.1.16

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 (123) hide show
  1. package/dist/agent-runtime.d.mts +5 -2
  2. package/dist/agent-runtime.d.ts +5 -2
  3. package/dist/api/client.d.mts +3 -2
  4. package/dist/api/client.d.ts +3 -2
  5. package/dist/api/route-manager.d.mts +5 -2
  6. package/dist/api/route-manager.d.ts +5 -2
  7. package/dist/api/runtime.d.mts +3 -2
  8. package/dist/api/runtime.d.ts +3 -2
  9. package/dist/{api-client-C8d7BZNp.d.mts → api-client-B-n3pm_Q.d.mts} +2 -1
  10. package/dist/{api-client-BWrEbxfO.d.ts → api-client-C0_NZEBl.d.ts} +2 -1
  11. package/dist/api.d.mts +7 -4
  12. package/dist/api.d.ts +7 -4
  13. package/dist/{app-wIYse61b.d.ts → app-AyjEsCBq.d.ts} +3 -3
  14. package/dist/{app-B3nVSjen.d.mts → app-CYPHeOo_.d.mts} +3 -3
  15. package/dist/app-markdown.d.mts +6 -3
  16. package/dist/app-markdown.d.ts +6 -3
  17. package/dist/{chunk-FOGLGRDS.mjs → chunk-7HDZYYS4.mjs} +100 -8
  18. package/dist/{chunk-UE75PB52.mjs → chunk-IL5RWYK7.mjs} +1 -1
  19. package/dist/{chunk-GNTPTTLA.mjs → chunk-IXTEENRS.mjs} +1 -1
  20. package/dist/{chunk-JRF3C33L.mjs → chunk-NHHKW2T6.mjs} +5 -4
  21. package/dist/{chunk-NJ47VORC.mjs → chunk-NUD6XBMO.mjs} +1 -1
  22. package/dist/{chunk-FBHGHMOA.mjs → chunk-TYVVIQ5M.mjs} +10 -7
  23. package/dist/{chunk-W7IVHTOP.mjs → chunk-UQZPTIML.mjs} +15 -2
  24. package/dist/{chunk-S3QW3BIS.mjs → chunk-VVTREAG5.mjs} +89 -4
  25. package/dist/{client-plugins-C1EgdoJM.d.mts → client-plugins-CIPRtSsW.d.mts} +16 -4
  26. package/dist/{client-plugins-CslwYp3E.d.ts → client-plugins-CqVtZi5X.d.ts} +16 -4
  27. package/dist/client-plugins.d.mts +5 -2
  28. package/dist/client-plugins.d.ts +5 -2
  29. package/dist/client.d.mts +8 -7
  30. package/dist/client.d.ts +8 -7
  31. package/dist/config.d.mts +5 -2
  32. package/dist/config.d.ts +5 -2
  33. package/dist/{devtools-PCGEBRSC.mjs → devtools-IU7LKZOH.mjs} +2 -2
  34. package/dist/docs.cjs +74 -3
  35. package/dist/docs.mjs +3 -3
  36. package/dist/{route-C6UClI1z.d.mts → endpoint-Bu3XgeMK.d.mts} +3 -128
  37. package/dist/{route-CHBaW55F.d.ts → endpoint-kSAxE52R.d.ts} +3 -128
  38. package/dist/env.cjs +101 -8
  39. package/dist/env.d.mts +20 -2
  40. package/dist/env.d.ts +20 -2
  41. package/dist/env.mjs +3 -1
  42. package/dist/index.cjs +212 -19
  43. package/dist/index.d.mts +16 -15
  44. package/dist/index.d.ts +16 -15
  45. package/dist/index.mjs +20 -8
  46. package/dist/integrations.d.mts +5 -2
  47. package/dist/integrations.d.ts +5 -2
  48. package/dist/internal/app-markdown-runtime.d.mts +5 -2
  49. package/dist/internal/app-markdown-runtime.d.ts +5 -2
  50. package/dist/internal/build-runtime.cjs +264 -169
  51. package/dist/internal/build-runtime.d.mts +7 -4
  52. package/dist/internal/build-runtime.d.ts +7 -4
  53. package/dist/internal/build-runtime.mjs +6 -6
  54. package/dist/internal/cli-runtime.cjs +68 -4
  55. package/dist/internal/cli-runtime.mjs +2 -2
  56. package/dist/internal/client-error-overlay.cjs +1 -1
  57. package/dist/internal/client-error-overlay.mjs +1 -1
  58. package/dist/internal/compression-runtime.d.mts +5 -2
  59. package/dist/internal/compression-runtime.d.ts +5 -2
  60. package/dist/internal/config-runtime.cjs +68 -4
  61. package/dist/internal/config-runtime.d.mts +6 -3
  62. package/dist/internal/config-runtime.d.ts +6 -3
  63. package/dist/internal/config-runtime.mjs +2 -2
  64. package/dist/internal/product-telemetry-runtime.cjs +1 -1
  65. package/dist/internal/product-telemetry-runtime.mjs +1 -1
  66. package/dist/internal/production-runtime.d.mts +11 -8
  67. package/dist/internal/production-runtime.d.ts +11 -8
  68. package/dist/{metadata-BsUcOEXg.d.ts → metadata-8g__AMPM.d.ts} +1 -1
  69. package/dist/{metadata-B1bxCPUY.d.mts → metadata-OMX6wFNf.d.mts} +1 -1
  70. package/dist/middleware.d.mts +7 -4
  71. package/dist/middleware.d.ts +7 -4
  72. package/dist/{nitro-ICBP5APY.mjs → nitro-3N4ZXRYM.mjs} +5 -2
  73. package/dist/plugin.cjs +108 -7
  74. package/dist/plugin.d.mts +5 -2
  75. package/dist/plugin.d.ts +5 -2
  76. package/dist/plugin.mjs +3 -3
  77. package/dist/{production-runtime-CsNn2-zx.d.ts → production-runtime-BJh7o6Cr.d.ts} +1 -1
  78. package/dist/{production-runtime-BDllolVh.d.mts → production-runtime-W3M0eNDV.d.mts} +1 -1
  79. package/dist/{render-plan-EG4hNFjy.d.ts → render-plan-Be4ZGTJP.d.ts} +1 -1
  80. package/dist/{render-plan-CNUlzylR.d.mts → render-plan-io7pvDNc.d.mts} +1 -1
  81. package/dist/renderer-client.d.mts +5 -4
  82. package/dist/renderer-client.d.ts +5 -4
  83. package/dist/{request-Blh_f7Z3.d.mts → request-DZkHYQ89.d.mts} +1 -1
  84. package/dist/{request-DsVSQVfD.d.ts → request-G8JhKr4F.d.ts} +1 -1
  85. package/dist/request.d.mts +6 -3
  86. package/dist/request.d.ts +6 -3
  87. package/dist/route-BxNJT447.d.ts +128 -0
  88. package/dist/route-C_eLaFTZ.d.mts +128 -0
  89. package/dist/{route-rendering-hUETRCbM.d.ts → route-rendering-BcLLPJgN.d.ts} +1 -1
  90. package/dist/{route-rendering-LT4XSoQK.d.mts → route-rendering-CbAKr1TY.d.mts} +1 -1
  91. package/dist/routes.d.mts +4 -2
  92. package/dist/routes.d.ts +4 -2
  93. package/dist/server-fn-client.d.mts +3 -2
  94. package/dist/server-fn-client.d.ts +3 -2
  95. package/dist/server-fn.cjs +141 -3
  96. package/dist/server-fn.d.mts +72 -1
  97. package/dist/server-fn.d.ts +72 -1
  98. package/dist/server-fn.mjs +12 -1
  99. package/dist/server-plugins.d.mts +6 -3
  100. package/dist/server-plugins.d.ts +6 -3
  101. package/dist/server-query-client.d.mts +1 -0
  102. package/dist/server-query-client.d.ts +1 -0
  103. package/dist/server-query.cjs +60 -3
  104. package/dist/server-query.d.mts +6 -1
  105. package/dist/server-query.d.ts +6 -1
  106. package/dist/server-query.mjs +3 -2
  107. package/dist/server.cjs +161 -11
  108. package/dist/server.d.mts +9 -8
  109. package/dist/server.d.ts +9 -8
  110. package/dist/server.mjs +6 -6
  111. package/dist/{spa-router-csKR9Ebj.d.mts → spa-router-BcS_4nqm.d.mts} +2 -2
  112. package/dist/{spa-router-Y_2FSJQK.d.ts → spa-router-BzFBUJkn.d.ts} +2 -2
  113. package/dist/testing.d.mts +5 -3
  114. package/dist/testing.d.ts +5 -3
  115. package/dist/{utils-DR2wfZAn.d.mts → utils-5kQP1mFR.d.mts} +1 -1
  116. package/dist/{utils-jISOE9SD.d.ts → utils-C4yrAhNc.d.ts} +1 -1
  117. package/dist/version.cjs +1 -1
  118. package/dist/version.mjs +1 -1
  119. package/dist/vite.cjs +246 -149
  120. package/dist/vite.d.mts +5 -2
  121. package/dist/vite.d.ts +5 -2
  122. package/dist/vite.mjs +3 -3
  123. package/package.json +1 -1
package/dist/docs.cjs CHANGED
@@ -4640,6 +4640,7 @@ var import_node_path6 = require("path");
4640
4640
 
4641
4641
  // src/env.ts
4642
4642
  var FARM_ENV_SYMBOL = /* @__PURE__ */ Symbol.for("farm.env");
4643
+ var FARM_ENV_RUNTIME_SYMBOL = /* @__PURE__ */ Symbol.for("farm.env.runtime");
4643
4644
  var farmEnvGlobal = globalThis;
4644
4645
  var currentEnv = getInitialEnv();
4645
4646
  var env = createEnvProxy("server");
@@ -4653,7 +4654,7 @@ function createEnvProxy(scope) {
4653
4654
  return void 0;
4654
4655
  }
4655
4656
  const env2 = getEnvScope(scope);
4656
- return env2[property];
4657
+ return scope === "server" ? readServerEnvKey(env2, property) : env2[property];
4657
4658
  },
4658
4659
  ownKeys() {
4659
4660
  return Reflect.ownKeys(getEnvScope(scope));
@@ -4677,12 +4678,75 @@ function createEnvProxy(scope) {
4677
4678
  }
4678
4679
  __name(createEnvProxy, "createEnvProxy");
4679
4680
  function getEnvScope(scope) {
4681
+ const env2 = getCurrentEnv();
4680
4682
  if (scope === "server") {
4681
4683
  assertServerEnvAccess();
4684
+ readRuntimeServerEnv(env2);
4682
4685
  }
4683
- return getCurrentEnv()[scope] || {};
4686
+ return env2[scope] || {};
4684
4687
  }
4685
4688
  __name(getEnvScope, "getEnvScope");
4689
+ function readServerEnvKey(server, key) {
4690
+ const value = server[key];
4691
+ if (value === void 0) {
4692
+ const state = getCurrentEnv()[FARM_ENV_RUNTIME_SYMBOL];
4693
+ if (state && key in state.pending && !state.warned.has(key)) {
4694
+ state.warned.add(key);
4695
+ console.warn(
4696
+ `[Farm] Server env "${key}" was set when this app was built but is not set where the server runs, so it reads as undefined. Farm reads server env at runtime and does not store it in the build output; set "${key}" in the server's environment.`
4697
+ );
4698
+ }
4699
+ }
4700
+ return value;
4701
+ }
4702
+ __name(readServerEnvKey, "readServerEnvKey");
4703
+ function readRuntimeServerEnv(env2) {
4704
+ const state = env2[FARM_ENV_RUNTIME_SYMBOL];
4705
+ if (!state) return;
4706
+ const source = getProcessEnv();
4707
+ for (const [key, type] of Object.entries(state.pending)) {
4708
+ const raw = source[key];
4709
+ if (raw === void 0) continue;
4710
+ env2.server[key] = coerceRuntimeEnvValue(raw, type);
4711
+ delete state.pending[key];
4712
+ }
4713
+ }
4714
+ __name(readRuntimeServerEnv, "readRuntimeServerEnv");
4715
+ function coerceRuntimeEnvValue(raw, type) {
4716
+ if (type === "number") {
4717
+ const value = Number(raw);
4718
+ return raw.trim() !== "" && Number.isFinite(value) ? value : raw;
4719
+ }
4720
+ if (type === "boolean") {
4721
+ if (/^(true|1)$/i.test(raw.trim())) return true;
4722
+ if (/^(false|0|)$/i.test(raw.trim())) return false;
4723
+ return raw;
4724
+ }
4725
+ if (type === "json") {
4726
+ try {
4727
+ return JSON.parse(raw);
4728
+ } catch {
4729
+ return raw;
4730
+ }
4731
+ }
4732
+ return raw;
4733
+ }
4734
+ __name(coerceRuntimeEnvValue, "coerceRuntimeEnvValue");
4735
+ function prepareEnv(env2) {
4736
+ const normalized = normalizeResolvedEnv(env2);
4737
+ const runtime = env2.runtime?.server;
4738
+ if (!isRecord(runtime) || Object.keys(runtime).length === 0) return normalized;
4739
+ const prepared = { server: { ...normalized.server }, public: normalized.public };
4740
+ Object.defineProperty(prepared, FARM_ENV_RUNTIME_SYMBOL, {
4741
+ value: {
4742
+ pending: { ...runtime },
4743
+ warned: /* @__PURE__ */ new Set()
4744
+ },
4745
+ enumerable: false
4746
+ });
4747
+ return prepared;
4748
+ }
4749
+ __name(prepareEnv, "prepareEnv");
4686
4750
  function assertServerEnvAccess() {
4687
4751
  if (typeof window !== "undefined") {
4688
4752
  throw new Error("Farm server env is not available in the browser. Use publicEnv.");
@@ -4713,7 +4777,7 @@ __name(getCurrentEnv, "getCurrentEnv");
4713
4777
  function getInjectedEnv() {
4714
4778
  try {
4715
4779
  if (typeof __FARM_ENV__ !== "undefined" && __FARM_ENV__) {
4716
- return normalizeResolvedEnv(__FARM_ENV__);
4780
+ return prepareEnv(__FARM_ENV__);
4717
4781
  }
4718
4782
  } catch {
4719
4783
  }
@@ -4741,6 +4805,13 @@ function isRecord(value) {
4741
4805
  return !!value && typeof value === "object" && !Array.isArray(value);
4742
4806
  }
4743
4807
  __name(isRecord, "isRecord");
4808
+ function getProcessEnv() {
4809
+ if (typeof process !== "undefined" && process.env) {
4810
+ return process.env;
4811
+ }
4812
+ return {};
4813
+ }
4814
+ __name(getProcessEnv, "getProcessEnv");
4744
4815
 
4745
4816
  // src/app-markdown-config.ts
4746
4817
  var import_node_path7 = __toESM(require("path"));
package/dist/docs.mjs CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  createFarmDocsAdapterHandler,
5
5
  hasFarmDocsRuntimeAdapter,
6
6
  isFarmDocsAPIRequest
7
- } from "./chunk-NJ47VORC.mjs";
7
+ } from "./chunk-NUD6XBMO.mjs";
8
8
  import {
9
9
  createFarmDocsHandler,
10
10
  discoverFarmDocsPages,
@@ -16,7 +16,7 @@ import {
16
16
  } from "./chunk-MOQNHLTS.mjs";
17
17
  import "./chunk-UP4CW6WP.mjs";
18
18
  import "./chunk-TFQG7TBC.mjs";
19
- import "./chunk-GNTPTTLA.mjs";
19
+ import "./chunk-IXTEENRS.mjs";
20
20
  import "./chunk-XZNTNMHT.mjs";
21
21
  import "./chunk-TVGP4BBZ.mjs";
22
22
  import "./chunk-FZC7EEPM.mjs";
@@ -28,7 +28,7 @@ import "./chunk-Q3MDL7TM.mjs";
28
28
  import "./chunk-G2KY33I6.mjs";
29
29
  import "./chunk-4L7SZOHZ.mjs";
30
30
  import "./chunk-QCFFHV5H.mjs";
31
- import "./chunk-FOGLGRDS.mjs";
31
+ import "./chunk-7HDZYYS4.mjs";
32
32
  import "./chunk-FA2W42OV.mjs";
33
33
  import "./chunk-6SCB2MXB.mjs";
34
34
  import "./chunk-MUUZJLCI.mjs";
@@ -129,7 +129,7 @@ type MaybePromise<T> = T | Promise<T>;
129
129
  type Simplify<T> = {
130
130
  [TKey in keyof T]: T[TKey];
131
131
  } & {};
132
- type UnionToIntersection$1<T> = (T extends unknown ? (value: T) => void : never) extends (value: infer TIntersection) => void ? TIntersection : never;
132
+ type UnionToIntersection<T> = (T extends unknown ? (value: T) => void : never) extends (value: infer TIntersection) => void ? TIntersection : never;
133
133
  type InferOutput<T> = RouteSchemaOutput<T>;
134
134
  type InferInput<T> = T extends {
135
135
  _input: infer I;
@@ -222,7 +222,7 @@ type ValidateEndpointMiddlewares<TMiddlewares extends readonly AnyEndpointMiddle
222
222
  };
223
223
  type ContextFromMiddlewareResult<TResult> = Exclude<TResult, Response | boolean> extends infer TContext ? [TContext] extends [never] ? {} : TContext extends object ? TContext : {} : {};
224
224
  type ContextFromMiddleware<TMiddleware> = TMiddleware extends (...args: any[]) => infer TResult ? ContextFromMiddlewareResult<Awaited<TResult>> : {};
225
- type InferEndpointMiddlewareContext<TMiddlewares extends readonly ((...args: any[]) => any)[], TContext extends object = {}> = TMiddlewares extends readonly [infer TMiddleware, ...infer TRest] ? TMiddleware extends (...args: any[]) => any ? TRest extends readonly ((...args: any[]) => any)[] ? InferEndpointMiddlewareContext<TRest, Simplify<TContext & ContextFromMiddleware<TMiddleware>>> : Simplify<TContext> : Simplify<TContext> : number extends TMiddlewares["length"] ? Simplify<TContext & UnionToIntersection$1<ContextFromMiddleware<TMiddlewares[number]>>> : Simplify<TContext>;
225
+ type InferEndpointMiddlewareContext<TMiddlewares extends readonly ((...args: any[]) => any)[], TContext extends object = {}> = TMiddlewares extends readonly [infer TMiddleware, ...infer TRest] ? TMiddleware extends (...args: any[]) => any ? TRest extends readonly ((...args: any[]) => any)[] ? InferEndpointMiddlewareContext<TRest, Simplify<TContext & ContextFromMiddleware<TMiddleware>>> : Simplify<TContext> : Simplify<TContext> : number extends TMiddlewares["length"] ? Simplify<TContext & UnionToIntersection<ContextFromMiddleware<TMiddlewares[number]>>> : Simplify<TContext>;
226
226
  type EndpointOptions<TBody extends AnySchema = never, TQuery extends AnySchema = never, THeaders extends AnySchema = never, TMiddlewares extends readonly AnyEndpointMiddleware[] = readonly [], TErrors extends EndpointErrorDefinitions = {}> = {
227
227
  method?: "GET" | "HEAD" | "QUERY" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS";
228
228
  body?: TBody;
@@ -364,129 +364,4 @@ declare function OPTIONS<T = any>(handler: EndpointHandler<never, never, never,
364
364
  declare function OPTIONS<const TOptions extends MethodlessEndpointOptions, TResponse = any>(options: TOptions, handler: ValidatedEndpointHandlerFromOptions<TOptions, TResponse>): CreatedEndpointFromOptions<TOptions, TResponse>;
365
365
  declare function OPTIONS<TBody extends AnySchema = never, TQuery extends AnySchema = never, THeaders extends AnySchema = never, TResponse = any>(options: Omit<EndpointOptions<TBody, TQuery, THeaders, readonly []>, "method">, handler: EndpointHandler<TBody, TQuery, THeaders, TResponse>): CreatedEndpoint<TBody, TQuery, THeaders, TResponse>;
366
366
 
367
- type RouteMethod = "GET" | "HEAD" | "QUERY" | "POST" | "PUT" | "PATCH" | "DELETE" | "OPTIONS";
368
- type RoutePathParams<Path extends string> = Path extends `${infer Head}/${infer Tail}` ? RoutePathParams<Head> & RoutePathParams<Tail> : Path extends `[[...${infer Name}]]` ? {
369
- [K in Name]?: string[];
370
- } : Path extends `[...${infer Name}]` ? {
371
- [K in Name]: string[];
372
- } : Path extends `[${infer Name}]` ? {
373
- [K in Name]: string;
374
- } : {};
375
- interface RouteInputSchemas {
376
- body?: RouteSchema;
377
- query?: RouteSchema;
378
- params?: RouteSchema;
379
- headers?: RouteSchema;
380
- }
381
- type Input<I, K extends PropertyKey> = K extends keyof I ? RouteSchemaInput<I[K]> : never;
382
- type Output<I, K extends PropertyKey, Fallback = unknown> = K extends keyof I ? RouteSchemaOutput<I[K]> : Fallback;
383
- /** JSON responses have wire types, not server-side instances such as Date. */
384
- type RouteJSON<T> = T extends Response ? unknown : T extends {
385
- toJSON(): infer J;
386
- } ? RouteJSON<J> : T extends bigint | symbol | ((...args: any[]) => any) ? never : T extends readonly (infer V)[] ? RouteJSON<V>[] : T extends object ? {
387
- [K in keyof T]: RouteJSON<T[K]>;
388
- } : T;
389
- type RouteDefinition<P extends string = string, M extends RouteMethod = RouteMethod, E = any> = {
390
- readonly path: P;
391
- readonly method: M;
392
- readonly endpoint: E;
393
- };
394
- type RouteEndpoint<P extends string, I extends RouteInputSchemas, R> = TypedEndpoint<Output<I, "body">, Input<I, "query">, RouteJSON<R>, Input<I, "headers">, never, Input<I, "body">> & {
395
- __types: {
396
- params: RoutePathParams<P>;
397
- inputHeaders: Input<I, "headers">;
398
- };
399
- };
400
- type TrimStart<P extends string> = P extends `/${infer Rest}` ? TrimStart<Rest> : P;
401
- type Join<P extends string, C extends string> = C extends "" ? P : `${P}/${TrimStart<C>}`;
402
- type ParamsCheck<P extends string, I extends RouteInputSchemas> = I extends {
403
- params: infer S;
404
- } ? Exclude<keyof RoutePathParams<P>, keyof RouteSchemaOutput<S>> extends never ? Exclude<keyof RouteSchemaOutput<S>, keyof RoutePathParams<P>> extends never ? unknown : {
405
- __error_unknown_route_params: never;
406
- } : {
407
- __error_missing_route_params: never;
408
- } : unknown;
409
- type RouteMiddlewareResults = readonly (EndpointMiddlewareResult | Promise<EndpointMiddlewareResult>)[];
410
- type RouteMiddlewares<Results extends readonly unknown[]> = {
411
- readonly [K in keyof Results]: (context: Parameters<AnyEndpointMiddleware>[0]) => Results[K];
412
- };
413
- type RouteOptions<P extends string, I extends RouteInputSchemas, O extends RouteSchema | undefined, R, MiddlewareResults extends RouteMiddlewareResults = RouteMiddlewareResults> = {
414
- input?: I & ParamsCheck<P, I>;
415
- /** Validate plain JSON handler results. Raw Response/stream results are never buffered. */
416
- output?: O;
417
- /** Opt this app-owned endpoint into an installed MCP transport. */
418
- mcp?: EndpointMCPOptions;
419
- middleware?: RouteMiddlewares<MiddlewareResults>;
420
- handler(request: Request, context: {
421
- input: {
422
- body: Output<I, "body">;
423
- query: Output<I, "query", Record<string, string | string[]>>;
424
- headers: Output<I, "headers", Record<string, string>>;
425
- params: Output<I, "params", RoutePathParams<P>>;
426
- };
427
- params: Output<I, "params", RoutePathParams<P>>;
428
- context: Readonly<InferEndpointMiddlewareContext<RouteMiddlewares<MiddlewareResults>>>;
429
- }): R | Promise<R>;
430
- };
431
- type RouteBuilder<P extends string, M extends RouteMethod> = <const C extends string, const MiddlewareResults extends RouteMiddlewareResults, const I extends RouteInputSchemas = {}, O extends RouteSchema | undefined = undefined, R = unknown>(path: C, options: RouteOptions<Join<P, C>, I, O, R, MiddlewareResults>) => RouteDefinition<Join<P, C>, M, RouteEndpoint<Join<P, C>, I, Extract<Awaited<R>, Response> extends never ? O extends RouteSchema ? RouteSchemaOutput<O> : Awaited<R> : unknown>>;
432
- type RouteFactory<P extends string = ""> = {
433
- [M in Lowercase<RouteMethod>]: RouteBuilder<P, Uppercase<M> & RouteMethod>;
434
- } & {
435
- /** Return a new builder; never mutate the parent scope. */
436
- scope<const C extends string>(path: C): RouteFactory<Join<P, C>>;
437
- };
438
- type PluginRoutes = readonly RouteDefinition[];
439
- interface PluginLocalAPIEndpoint {
440
- readonly path: string;
441
- readonly method: RouteMethod;
442
- readonly input: Readonly<RouteInputSchemas>;
443
- readonly output?: RouteSchema;
444
- readonly mcp?: EndpointMCPOptions;
445
- invoke(request: Request, params?: Readonly<Record<string, string | string[]>>): Promise<Response>;
446
- }
447
- /**
448
- * Read-only access to app-owned API endpoints while plugin routes are mounted.
449
- * Plugin routes are intentionally excluded so a plugin cannot recurse through
450
- * itself or depend on plugin registration order.
451
- */
452
- interface PluginLocalAPI {
453
- /** False during type-only route discovery, where app endpoint modules are unavailable. */
454
- readonly available: boolean;
455
- get(method: RouteMethod, path: string): PluginLocalAPIEndpoint | undefined;
456
- /** Enumerate app-owned endpoints. Plugin routes are excluded. */
457
- list(): readonly PluginLocalAPIEndpoint[];
458
- }
459
- type PluginRoutesFactory<R extends PluginRoutes = PluginRoutes> = (context: {
460
- route: RouteFactory;
461
- api: PluginLocalAPI;
462
- }) => R;
463
- declare function createRouteFactory(): RouteFactory;
464
- type UnionToIntersection<U> = (U extends unknown ? (v: U) => void : never) extends (v: infer I) => void ? I : never;
465
- type RouteTree<P extends string, M extends string, E> = P extends `${infer Head}/${infer Tail}` ? {
466
- [K in Head]: RouteTree<Tail, M, E>;
467
- } : P extends "" ? {
468
- [K in Lowercase<M>]: E;
469
- } : {
470
- [K in P]: {
471
- [Method in Lowercase<M>]: E;
472
- };
473
- };
474
- type HasMethodSegment<P extends string> = P extends `${infer H}/${infer T}` ? H extends Lowercase<RouteMethod> ? true : HasMethodSegment<T> : P extends Lowercase<RouteMethod> ? true : false;
475
- type DefinitionTree<D> = D extends RouteDefinition<infer P, infer M, infer E> ? string extends P ? {} : (P extends `/api/integrations${string}` ? true : HasMethodSegment<P>) extends true ? {
476
- [K in P extends `/api/${infer C}` ? `/${C}` : "/"]: {
477
- [Method in Lowercase<M>]: E;
478
- };
479
- } : RouteTree<P extends `/api/${infer C}` ? C : "", M, E> : {};
480
- type PluginAPIRouter<C> = C extends {
481
- plugins: readonly (infer P)[];
482
- } ? UnionToIntersection<P extends {
483
- routes?: PluginRoutesFactory<infer R>;
484
- } ? DefinitionTree<R[number]> : {}> : {};
485
- declare function resolvePluginRoutes(plugins?: readonly {
486
- name: string;
487
- routes?: PluginRoutesFactory;
488
- }[], context?: {
489
- api?: PluginLocalAPI;
490
- }): PluginRoutes;
491
-
492
- export { type RouteOptions as $, type AnyEndpointMiddleware as A, type TypedFormData as B, type MultipartSchema as C, DELETE as D, EndpointFailure as E, type FarmStreamResponse as F, GET as G, HEAD as H, type InferEndpointMiddlewareContext as I, type FarmAPIStream as J, multipart as K, isMultipartSchema as L, type MultipartField as M, toFormData as N, OPTIONS as O, type PluginRoutesFactory as P, QUERY as Q, jsonStream as R, isJSONStreamResponse as S, type TypedEndpoint as T, readJSONStream as U, isFarmAPIStream as V, type RouteMethod as W, type RoutePathParams as X, type RouteInputSchemas as Y, type RouteJSON as Z, type RouteDefinition as _, type EndpointOpenAPIMetadata as a, type RouteFactory as a0, type PluginRoutes as a1, type PluginLocalAPIEndpoint as a2, type PluginLocalAPI as a3, createRouteFactory as a4, type PluginAPIRouter as a5, resolvePluginRoutes as a6, type RouteSchema as a7, type RouteSchemaOutput as a8, type RouteSchemaInput as a9, type OpenAPISecurityMode as aa, type EndpointErrorSchema as b, type EndpointErrorDefinition as c, type EndpointErrorDefinitions as d, type EndpointErrorContracts as e, type EndpointErrorHandler as f, type EndpointFail as g, type EndpointParamValue as h, isEndpointFailure as i, type EndpointParams as j, type EndpointMiddlewareContext as k, type EndpointMiddlewareResult as l, type EndpointMiddleware as m, type EndpointInvalidationTarget as n, type EndpointInvalidationContext as o, parseRouteSchema as p, type EndpointInvalidations as q, type EndpointMCPMetadata as r, type EndpointMCPOptions as s, type EndpointOptions as t, type EndpointHandler as u, createEndpoint as v, POST as w, PUT as x, PATCH as y, type MultipartValues as z };
367
+ export { type AnyEndpointMiddleware as A, type MultipartValues as B, type TypedFormData as C, DELETE as D, type EndpointMiddlewareResult as E, type MultipartSchema as F, GET as G, HEAD as H, type InferEndpointMiddlewareContext as I, type FarmStreamResponse as J, type FarmAPIStream as K, multipart as L, type MultipartField as M, isMultipartSchema as N, OPTIONS as O, POST as P, QUERY as Q, type RouteSchema as R, toFormData as S, type TypedEndpoint as T, jsonStream as U, isJSONStreamResponse as V, readJSONStream as W, isFarmAPIStream as X, type OpenAPISecurityMode as Y, type RouteSchemaOutput as a, type EndpointMCPOptions as b, type RouteSchemaInput as c, type EndpointMCPMetadata as d, EndpointFailure as e, type EndpointOpenAPIMetadata as f, type EndpointErrorSchema as g, type EndpointErrorDefinition as h, type EndpointErrorDefinitions as i, type EndpointErrorContracts as j, type EndpointErrorHandler as k, type EndpointFail as l, isEndpointFailure as m, type EndpointParamValue as n, type EndpointParams as o, parseRouteSchema as p, type EndpointMiddlewareContext as q, type EndpointMiddleware as r, type EndpointInvalidationTarget as s, type EndpointInvalidationContext as t, type EndpointInvalidations as u, type EndpointOptions as v, type EndpointHandler as w, createEndpoint as x, PUT as y, PATCH as z };
@@ -129,7 +129,7 @@ type MaybePromise<T> = T | Promise<T>;
129
129
  type Simplify<T> = {
130
130
  [TKey in keyof T]: T[TKey];
131
131
  } & {};
132
- type UnionToIntersection$1<T> = (T extends unknown ? (value: T) => void : never) extends (value: infer TIntersection) => void ? TIntersection : never;
132
+ type UnionToIntersection<T> = (T extends unknown ? (value: T) => void : never) extends (value: infer TIntersection) => void ? TIntersection : never;
133
133
  type InferOutput<T> = RouteSchemaOutput<T>;
134
134
  type InferInput<T> = T extends {
135
135
  _input: infer I;
@@ -222,7 +222,7 @@ type ValidateEndpointMiddlewares<TMiddlewares extends readonly AnyEndpointMiddle
222
222
  };
223
223
  type ContextFromMiddlewareResult<TResult> = Exclude<TResult, Response | boolean> extends infer TContext ? [TContext] extends [never] ? {} : TContext extends object ? TContext : {} : {};
224
224
  type ContextFromMiddleware<TMiddleware> = TMiddleware extends (...args: any[]) => infer TResult ? ContextFromMiddlewareResult<Awaited<TResult>> : {};
225
- type InferEndpointMiddlewareContext<TMiddlewares extends readonly ((...args: any[]) => any)[], TContext extends object = {}> = TMiddlewares extends readonly [infer TMiddleware, ...infer TRest] ? TMiddleware extends (...args: any[]) => any ? TRest extends readonly ((...args: any[]) => any)[] ? InferEndpointMiddlewareContext<TRest, Simplify<TContext & ContextFromMiddleware<TMiddleware>>> : Simplify<TContext> : Simplify<TContext> : number extends TMiddlewares["length"] ? Simplify<TContext & UnionToIntersection$1<ContextFromMiddleware<TMiddlewares[number]>>> : Simplify<TContext>;
225
+ type InferEndpointMiddlewareContext<TMiddlewares extends readonly ((...args: any[]) => any)[], TContext extends object = {}> = TMiddlewares extends readonly [infer TMiddleware, ...infer TRest] ? TMiddleware extends (...args: any[]) => any ? TRest extends readonly ((...args: any[]) => any)[] ? InferEndpointMiddlewareContext<TRest, Simplify<TContext & ContextFromMiddleware<TMiddleware>>> : Simplify<TContext> : Simplify<TContext> : number extends TMiddlewares["length"] ? Simplify<TContext & UnionToIntersection<ContextFromMiddleware<TMiddlewares[number]>>> : Simplify<TContext>;
226
226
  type EndpointOptions<TBody extends AnySchema = never, TQuery extends AnySchema = never, THeaders extends AnySchema = never, TMiddlewares extends readonly AnyEndpointMiddleware[] = readonly [], TErrors extends EndpointErrorDefinitions = {}> = {
227
227
  method?: "GET" | "HEAD" | "QUERY" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS";
228
228
  body?: TBody;
@@ -364,129 +364,4 @@ declare function OPTIONS<T = any>(handler: EndpointHandler<never, never, never,
364
364
  declare function OPTIONS<const TOptions extends MethodlessEndpointOptions, TResponse = any>(options: TOptions, handler: ValidatedEndpointHandlerFromOptions<TOptions, TResponse>): CreatedEndpointFromOptions<TOptions, TResponse>;
365
365
  declare function OPTIONS<TBody extends AnySchema = never, TQuery extends AnySchema = never, THeaders extends AnySchema = never, TResponse = any>(options: Omit<EndpointOptions<TBody, TQuery, THeaders, readonly []>, "method">, handler: EndpointHandler<TBody, TQuery, THeaders, TResponse>): CreatedEndpoint<TBody, TQuery, THeaders, TResponse>;
366
366
 
367
- type RouteMethod = "GET" | "HEAD" | "QUERY" | "POST" | "PUT" | "PATCH" | "DELETE" | "OPTIONS";
368
- type RoutePathParams<Path extends string> = Path extends `${infer Head}/${infer Tail}` ? RoutePathParams<Head> & RoutePathParams<Tail> : Path extends `[[...${infer Name}]]` ? {
369
- [K in Name]?: string[];
370
- } : Path extends `[...${infer Name}]` ? {
371
- [K in Name]: string[];
372
- } : Path extends `[${infer Name}]` ? {
373
- [K in Name]: string;
374
- } : {};
375
- interface RouteInputSchemas {
376
- body?: RouteSchema;
377
- query?: RouteSchema;
378
- params?: RouteSchema;
379
- headers?: RouteSchema;
380
- }
381
- type Input<I, K extends PropertyKey> = K extends keyof I ? RouteSchemaInput<I[K]> : never;
382
- type Output<I, K extends PropertyKey, Fallback = unknown> = K extends keyof I ? RouteSchemaOutput<I[K]> : Fallback;
383
- /** JSON responses have wire types, not server-side instances such as Date. */
384
- type RouteJSON<T> = T extends Response ? unknown : T extends {
385
- toJSON(): infer J;
386
- } ? RouteJSON<J> : T extends bigint | symbol | ((...args: any[]) => any) ? never : T extends readonly (infer V)[] ? RouteJSON<V>[] : T extends object ? {
387
- [K in keyof T]: RouteJSON<T[K]>;
388
- } : T;
389
- type RouteDefinition<P extends string = string, M extends RouteMethod = RouteMethod, E = any> = {
390
- readonly path: P;
391
- readonly method: M;
392
- readonly endpoint: E;
393
- };
394
- type RouteEndpoint<P extends string, I extends RouteInputSchemas, R> = TypedEndpoint<Output<I, "body">, Input<I, "query">, RouteJSON<R>, Input<I, "headers">, never, Input<I, "body">> & {
395
- __types: {
396
- params: RoutePathParams<P>;
397
- inputHeaders: Input<I, "headers">;
398
- };
399
- };
400
- type TrimStart<P extends string> = P extends `/${infer Rest}` ? TrimStart<Rest> : P;
401
- type Join<P extends string, C extends string> = C extends "" ? P : `${P}/${TrimStart<C>}`;
402
- type ParamsCheck<P extends string, I extends RouteInputSchemas> = I extends {
403
- params: infer S;
404
- } ? Exclude<keyof RoutePathParams<P>, keyof RouteSchemaOutput<S>> extends never ? Exclude<keyof RouteSchemaOutput<S>, keyof RoutePathParams<P>> extends never ? unknown : {
405
- __error_unknown_route_params: never;
406
- } : {
407
- __error_missing_route_params: never;
408
- } : unknown;
409
- type RouteMiddlewareResults = readonly (EndpointMiddlewareResult | Promise<EndpointMiddlewareResult>)[];
410
- type RouteMiddlewares<Results extends readonly unknown[]> = {
411
- readonly [K in keyof Results]: (context: Parameters<AnyEndpointMiddleware>[0]) => Results[K];
412
- };
413
- type RouteOptions<P extends string, I extends RouteInputSchemas, O extends RouteSchema | undefined, R, MiddlewareResults extends RouteMiddlewareResults = RouteMiddlewareResults> = {
414
- input?: I & ParamsCheck<P, I>;
415
- /** Validate plain JSON handler results. Raw Response/stream results are never buffered. */
416
- output?: O;
417
- /** Opt this app-owned endpoint into an installed MCP transport. */
418
- mcp?: EndpointMCPOptions;
419
- middleware?: RouteMiddlewares<MiddlewareResults>;
420
- handler(request: Request, context: {
421
- input: {
422
- body: Output<I, "body">;
423
- query: Output<I, "query", Record<string, string | string[]>>;
424
- headers: Output<I, "headers", Record<string, string>>;
425
- params: Output<I, "params", RoutePathParams<P>>;
426
- };
427
- params: Output<I, "params", RoutePathParams<P>>;
428
- context: Readonly<InferEndpointMiddlewareContext<RouteMiddlewares<MiddlewareResults>>>;
429
- }): R | Promise<R>;
430
- };
431
- type RouteBuilder<P extends string, M extends RouteMethod> = <const C extends string, const MiddlewareResults extends RouteMiddlewareResults, const I extends RouteInputSchemas = {}, O extends RouteSchema | undefined = undefined, R = unknown>(path: C, options: RouteOptions<Join<P, C>, I, O, R, MiddlewareResults>) => RouteDefinition<Join<P, C>, M, RouteEndpoint<Join<P, C>, I, Extract<Awaited<R>, Response> extends never ? O extends RouteSchema ? RouteSchemaOutput<O> : Awaited<R> : unknown>>;
432
- type RouteFactory<P extends string = ""> = {
433
- [M in Lowercase<RouteMethod>]: RouteBuilder<P, Uppercase<M> & RouteMethod>;
434
- } & {
435
- /** Return a new builder; never mutate the parent scope. */
436
- scope<const C extends string>(path: C): RouteFactory<Join<P, C>>;
437
- };
438
- type PluginRoutes = readonly RouteDefinition[];
439
- interface PluginLocalAPIEndpoint {
440
- readonly path: string;
441
- readonly method: RouteMethod;
442
- readonly input: Readonly<RouteInputSchemas>;
443
- readonly output?: RouteSchema;
444
- readonly mcp?: EndpointMCPOptions;
445
- invoke(request: Request, params?: Readonly<Record<string, string | string[]>>): Promise<Response>;
446
- }
447
- /**
448
- * Read-only access to app-owned API endpoints while plugin routes are mounted.
449
- * Plugin routes are intentionally excluded so a plugin cannot recurse through
450
- * itself or depend on plugin registration order.
451
- */
452
- interface PluginLocalAPI {
453
- /** False during type-only route discovery, where app endpoint modules are unavailable. */
454
- readonly available: boolean;
455
- get(method: RouteMethod, path: string): PluginLocalAPIEndpoint | undefined;
456
- /** Enumerate app-owned endpoints. Plugin routes are excluded. */
457
- list(): readonly PluginLocalAPIEndpoint[];
458
- }
459
- type PluginRoutesFactory<R extends PluginRoutes = PluginRoutes> = (context: {
460
- route: RouteFactory;
461
- api: PluginLocalAPI;
462
- }) => R;
463
- declare function createRouteFactory(): RouteFactory;
464
- type UnionToIntersection<U> = (U extends unknown ? (v: U) => void : never) extends (v: infer I) => void ? I : never;
465
- type RouteTree<P extends string, M extends string, E> = P extends `${infer Head}/${infer Tail}` ? {
466
- [K in Head]: RouteTree<Tail, M, E>;
467
- } : P extends "" ? {
468
- [K in Lowercase<M>]: E;
469
- } : {
470
- [K in P]: {
471
- [Method in Lowercase<M>]: E;
472
- };
473
- };
474
- type HasMethodSegment<P extends string> = P extends `${infer H}/${infer T}` ? H extends Lowercase<RouteMethod> ? true : HasMethodSegment<T> : P extends Lowercase<RouteMethod> ? true : false;
475
- type DefinitionTree<D> = D extends RouteDefinition<infer P, infer M, infer E> ? string extends P ? {} : (P extends `/api/integrations${string}` ? true : HasMethodSegment<P>) extends true ? {
476
- [K in P extends `/api/${infer C}` ? `/${C}` : "/"]: {
477
- [Method in Lowercase<M>]: E;
478
- };
479
- } : RouteTree<P extends `/api/${infer C}` ? C : "", M, E> : {};
480
- type PluginAPIRouter<C> = C extends {
481
- plugins: readonly (infer P)[];
482
- } ? UnionToIntersection<P extends {
483
- routes?: PluginRoutesFactory<infer R>;
484
- } ? DefinitionTree<R[number]> : {}> : {};
485
- declare function resolvePluginRoutes(plugins?: readonly {
486
- name: string;
487
- routes?: PluginRoutesFactory;
488
- }[], context?: {
489
- api?: PluginLocalAPI;
490
- }): PluginRoutes;
491
-
492
- export { type RouteOptions as $, type AnyEndpointMiddleware as A, type TypedFormData as B, type MultipartSchema as C, DELETE as D, EndpointFailure as E, type FarmStreamResponse as F, GET as G, HEAD as H, type InferEndpointMiddlewareContext as I, type FarmAPIStream as J, multipart as K, isMultipartSchema as L, type MultipartField as M, toFormData as N, OPTIONS as O, type PluginRoutesFactory as P, QUERY as Q, jsonStream as R, isJSONStreamResponse as S, type TypedEndpoint as T, readJSONStream as U, isFarmAPIStream as V, type RouteMethod as W, type RoutePathParams as X, type RouteInputSchemas as Y, type RouteJSON as Z, type RouteDefinition as _, type EndpointOpenAPIMetadata as a, type RouteFactory as a0, type PluginRoutes as a1, type PluginLocalAPIEndpoint as a2, type PluginLocalAPI as a3, createRouteFactory as a4, type PluginAPIRouter as a5, resolvePluginRoutes as a6, type RouteSchema as a7, type RouteSchemaOutput as a8, type RouteSchemaInput as a9, type OpenAPISecurityMode as aa, type EndpointErrorSchema as b, type EndpointErrorDefinition as c, type EndpointErrorDefinitions as d, type EndpointErrorContracts as e, type EndpointErrorHandler as f, type EndpointFail as g, type EndpointParamValue as h, isEndpointFailure as i, type EndpointParams as j, type EndpointMiddlewareContext as k, type EndpointMiddlewareResult as l, type EndpointMiddleware as m, type EndpointInvalidationTarget as n, type EndpointInvalidationContext as o, parseRouteSchema as p, type EndpointInvalidations as q, type EndpointMCPMetadata as r, type EndpointMCPOptions as s, type EndpointOptions as t, type EndpointHandler as u, createEndpoint as v, POST as w, PUT as x, PATCH as y, type MultipartValues as z };
367
+ export { type AnyEndpointMiddleware as A, type MultipartValues as B, type TypedFormData as C, DELETE as D, type EndpointMiddlewareResult as E, type MultipartSchema as F, GET as G, HEAD as H, type InferEndpointMiddlewareContext as I, type FarmStreamResponse as J, type FarmAPIStream as K, multipart as L, type MultipartField as M, isMultipartSchema as N, OPTIONS as O, POST as P, QUERY as Q, type RouteSchema as R, toFormData as S, type TypedEndpoint as T, jsonStream as U, isJSONStreamResponse as V, readJSONStream as W, isFarmAPIStream as X, type OpenAPISecurityMode as Y, type RouteSchemaOutput as a, type EndpointMCPOptions as b, type RouteSchemaInput as c, type EndpointMCPMetadata as d, EndpointFailure as e, type EndpointOpenAPIMetadata as f, type EndpointErrorSchema as g, type EndpointErrorDefinition as h, type EndpointErrorDefinitions as i, type EndpointErrorContracts as j, type EndpointErrorHandler as k, type EndpointFail as l, isEndpointFailure as m, type EndpointParamValue as n, type EndpointParams as o, parseRouteSchema as p, type EndpointMiddlewareContext as q, type EndpointMiddleware as r, type EndpointInvalidationTarget as s, type EndpointInvalidationContext as t, type EndpointInvalidations as u, type EndpointOptions as v, type EndpointHandler as w, createEndpoint as x, PUT as y, PATCH as z };
package/dist/env.cjs CHANGED
@@ -21,6 +21,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  // src/env.ts
22
22
  var env_exports = {};
23
23
  __export(env_exports, {
24
+ createBundledEnv: () => createBundledEnv,
24
25
  env: () => env,
25
26
  getEnv: () => getEnv,
26
27
  getPublicEnv: () => getPublicEnv,
@@ -32,6 +33,7 @@ __export(env_exports, {
32
33
  });
33
34
  module.exports = __toCommonJS(env_exports);
34
35
  var FARM_ENV_SYMBOL = /* @__PURE__ */ Symbol.for("farm.env");
36
+ var FARM_ENV_RUNTIME_SYMBOL = /* @__PURE__ */ Symbol.for("farm.env.runtime");
35
37
  var farmEnvGlobal = globalThis;
36
38
  var currentEnv = getInitialEnv();
37
39
  function resolveEnv(config, source = getProcessEnv()) {
@@ -42,23 +44,43 @@ function resolveEnv(config, source = getProcessEnv()) {
42
44
  return resolved;
43
45
  }
44
46
  __name(resolveEnv, "resolveEnv");
47
+ function createBundledEnv(env2, source = getProcessEnv()) {
48
+ const resolved = normalizeResolvedEnv(env2 ?? {});
49
+ const server = {};
50
+ const runtime = {};
51
+ for (const [key, value] of Object.entries(resolved.server)) {
52
+ if (source[key] === void 0) {
53
+ server[key] = value;
54
+ } else {
55
+ runtime[key] = getRuntimeEnvType(value);
56
+ }
57
+ }
58
+ return {
59
+ server,
60
+ public: resolved.public,
61
+ ...Object.keys(runtime).length > 0 ? { runtime: { server: runtime } } : {}
62
+ };
63
+ }
64
+ __name(createBundledEnv, "createBundledEnv");
45
65
  function setEnv(env2) {
46
- currentEnv = normalizeResolvedEnv(env2);
66
+ currentEnv = prepareEnv(env2);
47
67
  if (typeof window === "undefined") {
48
68
  farmEnvGlobal[FARM_ENV_SYMBOL] = currentEnv;
49
69
  }
50
70
  }
51
71
  __name(setEnv, "setEnv");
52
72
  function getResolvedEnv() {
53
- return getCurrentEnv();
73
+ const env2 = getCurrentEnv();
74
+ if (typeof window === "undefined") readRuntimeServerEnv(env2);
75
+ return env2;
54
76
  }
55
77
  __name(getResolvedEnv, "getResolvedEnv");
56
78
  function getEnv(key) {
57
- assertServerEnvAccess();
79
+ const server = getEnvScope("server");
58
80
  if (key === void 0) {
59
- return getCurrentEnv().server;
81
+ return server;
60
82
  }
61
- return getCurrentEnv().server[key];
83
+ return readServerEnvKey(server, key);
62
84
  }
63
85
  __name(getEnv, "getEnv");
64
86
  function getPublicEnv(key) {
@@ -106,7 +128,7 @@ function createEnvProxy(scope) {
106
128
  return void 0;
107
129
  }
108
130
  const env2 = getEnvScope(scope);
109
- return env2[property];
131
+ return scope === "server" ? readServerEnvKey(env2, property) : env2[property];
110
132
  },
111
133
  ownKeys() {
112
134
  return Reflect.ownKeys(getEnvScope(scope));
@@ -130,12 +152,82 @@ function createEnvProxy(scope) {
130
152
  }
131
153
  __name(createEnvProxy, "createEnvProxy");
132
154
  function getEnvScope(scope) {
155
+ const env2 = getCurrentEnv();
133
156
  if (scope === "server") {
134
157
  assertServerEnvAccess();
158
+ readRuntimeServerEnv(env2);
135
159
  }
136
- return getCurrentEnv()[scope] || {};
160
+ return env2[scope] || {};
137
161
  }
138
162
  __name(getEnvScope, "getEnvScope");
163
+ function readServerEnvKey(server, key) {
164
+ const value = server[key];
165
+ if (value === void 0) {
166
+ const state = getCurrentEnv()[FARM_ENV_RUNTIME_SYMBOL];
167
+ if (state && key in state.pending && !state.warned.has(key)) {
168
+ state.warned.add(key);
169
+ console.warn(
170
+ `[Farm] Server env "${key}" was set when this app was built but is not set where the server runs, so it reads as undefined. Farm reads server env at runtime and does not store it in the build output; set "${key}" in the server's environment.`
171
+ );
172
+ }
173
+ }
174
+ return value;
175
+ }
176
+ __name(readServerEnvKey, "readServerEnvKey");
177
+ function readRuntimeServerEnv(env2) {
178
+ const state = env2[FARM_ENV_RUNTIME_SYMBOL];
179
+ if (!state) return;
180
+ const source = getProcessEnv();
181
+ for (const [key, type] of Object.entries(state.pending)) {
182
+ const raw = source[key];
183
+ if (raw === void 0) continue;
184
+ env2.server[key] = coerceRuntimeEnvValue(raw, type);
185
+ delete state.pending[key];
186
+ }
187
+ }
188
+ __name(readRuntimeServerEnv, "readRuntimeServerEnv");
189
+ function getRuntimeEnvType(value) {
190
+ if (typeof value === "number") return "number";
191
+ if (typeof value === "boolean") return "boolean";
192
+ if (value !== null && typeof value === "object" && !(value instanceof Date)) return "json";
193
+ return "string";
194
+ }
195
+ __name(getRuntimeEnvType, "getRuntimeEnvType");
196
+ function coerceRuntimeEnvValue(raw, type) {
197
+ if (type === "number") {
198
+ const value = Number(raw);
199
+ return raw.trim() !== "" && Number.isFinite(value) ? value : raw;
200
+ }
201
+ if (type === "boolean") {
202
+ if (/^(true|1)$/i.test(raw.trim())) return true;
203
+ if (/^(false|0|)$/i.test(raw.trim())) return false;
204
+ return raw;
205
+ }
206
+ if (type === "json") {
207
+ try {
208
+ return JSON.parse(raw);
209
+ } catch {
210
+ return raw;
211
+ }
212
+ }
213
+ return raw;
214
+ }
215
+ __name(coerceRuntimeEnvValue, "coerceRuntimeEnvValue");
216
+ function prepareEnv(env2) {
217
+ const normalized = normalizeResolvedEnv(env2);
218
+ const runtime = env2.runtime?.server;
219
+ if (!isRecord(runtime) || Object.keys(runtime).length === 0) return normalized;
220
+ const prepared = { server: { ...normalized.server }, public: normalized.public };
221
+ Object.defineProperty(prepared, FARM_ENV_RUNTIME_SYMBOL, {
222
+ value: {
223
+ pending: { ...runtime },
224
+ warned: /* @__PURE__ */ new Set()
225
+ },
226
+ enumerable: false
227
+ });
228
+ return prepared;
229
+ }
230
+ __name(prepareEnv, "prepareEnv");
139
231
  function assertServerEnvAccess() {
140
232
  if (typeof window !== "undefined") {
141
233
  throw new Error("Farm server env is not available in the browser. Use publicEnv.");
@@ -166,7 +258,7 @@ __name(getCurrentEnv, "getCurrentEnv");
166
258
  function getInjectedEnv() {
167
259
  try {
168
260
  if (typeof __FARM_ENV__ !== "undefined" && __FARM_ENV__) {
169
- return normalizeResolvedEnv(__FARM_ENV__);
261
+ return prepareEnv(__FARM_ENV__);
170
262
  }
171
263
  } catch {
172
264
  }
@@ -203,6 +295,7 @@ function getProcessEnv() {
203
295
  __name(getProcessEnv, "getProcessEnv");
204
296
  // Annotate the CommonJS export names for ESM import in node:
205
297
  0 && (module.exports = {
298
+ createBundledEnv,
206
299
  env,
207
300
  getEnv,
208
301
  getPublicEnv,
package/dist/env.d.mts CHANGED
@@ -31,8 +31,26 @@ type FarmPublicEnv = FarmEnvTypes extends {
31
31
  public: infer TPublic;
32
32
  } ? TPublic extends Record<string, any> ? TPublic : Record<string, unknown> : Record<string, unknown>;
33
33
  type FarmTypedEnv = ResolvedFarmEnv<FarmServerEnv, FarmPublicEnv>;
34
+ type FarmEnvRuntimeType = "string" | "number" | "boolean" | "json";
35
+ /**
36
+ * The env a server bundle carries. `runtime.server` lists server keys that are
37
+ * read from the server's environment instead of being stored in the bundle,
38
+ * with the type their parsed value had at build time.
39
+ */
40
+ interface BundledFarmEnv extends ResolvedFarmEnv {
41
+ runtime?: {
42
+ server: Record<string, FarmEnvRuntimeType>;
43
+ };
44
+ }
34
45
  declare function resolveEnv<TConfig extends FarmEnvConfig<any, any> | undefined>(config: TConfig, source?: Record<string, string | undefined>): InferEnv<NonNullable<TConfig>>;
35
- declare function setEnv(env: ResolvedFarmEnv): void;
46
+ /**
47
+ * Prepare resolved env for a server bundle. Server values that came from the
48
+ * build environment are left out and read from `process.env` when the server
49
+ * uses them, so secrets never land in build output and a restart picks up a
50
+ * rotated value. Values a parser produced without an env var (defaults) stay.
51
+ */
52
+ declare function createBundledEnv(env: ResolvedFarmEnv | FarmEnvConfig<any, any> | undefined, source?: Record<string, string | undefined>): BundledFarmEnv;
53
+ declare function setEnv(env: ResolvedFarmEnv | BundledFarmEnv): void;
36
54
  declare function getResolvedEnv<TEnv extends ResolvedFarmEnv = FarmTypedEnv>(): TEnv;
37
55
  declare function getEnv<TServer extends Record<string, any> = FarmServerEnv>(): TServer;
38
56
  declare function getEnv<TKey extends Extract<keyof FarmServerEnv, string>>(key: TKey): FarmServerEnv[TKey];
@@ -42,4 +60,4 @@ declare const env: FarmServerEnv;
42
60
  declare const serverEnv: Record<string, unknown>;
43
61
  declare const publicEnv: FarmPublicEnv;
44
62
 
45
- export { type EnvParser, type EnvSchema, type EnvShape, type FarmEnvConfig, type FarmEnvTypes, type FarmPublicEnv, type FarmServerEnv, type FarmTypedEnv, type InferEnv, type InferEnvParser, type InferEnvShape, type ResolvedFarmEnv, env, getEnv, getPublicEnv, getResolvedEnv, publicEnv, resolveEnv, serverEnv, setEnv };
63
+ export { type BundledFarmEnv, type EnvParser, type EnvSchema, type EnvShape, type FarmEnvConfig, type FarmEnvRuntimeType, type FarmEnvTypes, type FarmPublicEnv, type FarmServerEnv, type FarmTypedEnv, type InferEnv, type InferEnvParser, type InferEnvShape, type ResolvedFarmEnv, createBundledEnv, env, getEnv, getPublicEnv, getResolvedEnv, publicEnv, resolveEnv, serverEnv, setEnv };