@farm.js/core 0.1.0-beta.16 → 0.1.0-beta.17

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 (215) hide show
  1. package/dist/after.d.mts +25 -0
  2. package/dist/after.d.ts +25 -0
  3. package/dist/agent-runtime.d.mts +96 -0
  4. package/dist/agent-runtime.d.ts +96 -0
  5. package/dist/api/route-manager.d.mts +66 -0
  6. package/dist/api/route-manager.d.ts +66 -0
  7. package/dist/api/runtime.d.mts +3 -0
  8. package/dist/api/runtime.d.ts +3 -0
  9. package/dist/api.d.mts +48 -0
  10. package/dist/api.d.ts +48 -0
  11. package/dist/app-B0tE1I3o.d.ts +306 -0
  12. package/dist/app-Dv2JJb7X.d.mts +306 -0
  13. package/dist/app-markdown.d.mts +24 -0
  14. package/dist/app-markdown.d.ts +24 -0
  15. package/dist/cache.d.mts +192 -0
  16. package/dist/cache.d.ts +192 -0
  17. package/dist/{chunk-AN3PQVKH.mjs → chunk-2FLBZFPG.mjs} +9 -7
  18. package/dist/chunk-2FLBZFPG.mjs.map +1 -0
  19. package/dist/chunk-E257KFBU.mjs +227 -0
  20. package/dist/chunk-E257KFBU.mjs.map +1 -0
  21. package/dist/{chunk-SLDBGSC3.mjs → chunk-JAEAE27K.mjs} +2 -2
  22. package/dist/{chunk-T2KL7VEL.mjs → chunk-PZXBQKCH.mjs} +13 -4
  23. package/dist/chunk-PZXBQKCH.mjs.map +1 -0
  24. package/dist/{chunk-UXUAWNO5.mjs → chunk-RIXKJPGI.mjs} +117 -55
  25. package/dist/chunk-RIXKJPGI.mjs.map +1 -0
  26. package/dist/{chunk-OSWV5IJB.mjs → chunk-T2M5QANG.mjs} +32 -9
  27. package/dist/chunk-T2M5QANG.mjs.map +1 -0
  28. package/dist/{chunk-BWJC5ZOD.mjs → chunk-VFDBC3W7.mjs} +2 -2
  29. package/dist/{chunk-BWJC5ZOD.mjs.map → chunk-VFDBC3W7.mjs.map} +1 -1
  30. package/dist/chunk-recovery-lnQFzcQP.d.mts +26 -0
  31. package/dist/chunk-recovery-lnQFzcQP.d.ts +26 -0
  32. package/dist/client-BT1mFQas.d.mts +447 -0
  33. package/dist/client-Nn0q4eO4.d.ts +447 -0
  34. package/dist/client-cache-CIlyBlmx.d.ts +6 -0
  35. package/dist/client-cache-D-EZ7XVW.d.mts +6 -0
  36. package/dist/client-plugins-278AvYHE.d.mts +2021 -0
  37. package/dist/client-plugins-CTQAkr7R.d.ts +2021 -0
  38. package/dist/client-plugins.d.mts +24 -0
  39. package/dist/client-plugins.d.ts +24 -0
  40. package/dist/client.d.mts +452 -0
  41. package/dist/client.d.ts +452 -0
  42. package/dist/config.d.mts +31 -0
  43. package/dist/config.d.ts +31 -0
  44. package/dist/cron.d.mts +78 -0
  45. package/dist/cron.d.ts +78 -0
  46. package/dist/deferred.d.mts +42 -0
  47. package/dist/deferred.d.ts +42 -0
  48. package/dist/deployment.d.mts +36 -0
  49. package/dist/deployment.d.ts +36 -0
  50. package/dist/{devtools-E4YNCY5J.mjs → devtools-K2ERKGNI.mjs} +3 -3
  51. package/dist/docs.cjs.map +1 -1
  52. package/dist/docs.d.mts +80 -0
  53. package/dist/docs.d.ts +80 -0
  54. package/dist/docs.mjs +3 -3
  55. package/dist/env-types.d.mts +12 -0
  56. package/dist/env-types.d.ts +12 -0
  57. package/dist/env.d.mts +45 -0
  58. package/dist/env.d.ts +45 -0
  59. package/dist/environment/vite.d.mts +22 -0
  60. package/dist/environment/vite.d.ts +22 -0
  61. package/dist/environment.d.mts +18 -0
  62. package/dist/environment.d.ts +18 -0
  63. package/dist/font.d.mts +95 -0
  64. package/dist/font.d.ts +95 -0
  65. package/dist/headers.d.mts +22 -0
  66. package/dist/headers.d.ts +22 -0
  67. package/dist/i18n/client.d.mts +32 -0
  68. package/dist/i18n/client.d.ts +32 -0
  69. package/dist/i18n/index.d.mts +20 -0
  70. package/dist/i18n/index.d.ts +20 -0
  71. package/dist/i18n/server.d.mts +30 -0
  72. package/dist/i18n/server.d.ts +30 -0
  73. package/dist/image/server.d.mts +37 -0
  74. package/dist/image/server.d.ts +37 -0
  75. package/dist/image/sharp.d.mts +7 -0
  76. package/dist/image/sharp.d.ts +7 -0
  77. package/dist/image-config-Duob7wER.d.mts +50 -0
  78. package/dist/image-config-Duob7wER.d.ts +50 -0
  79. package/dist/image.d.mts +39 -0
  80. package/dist/image.d.ts +39 -0
  81. package/dist/index.cjs +293 -58
  82. package/dist/index.cjs.map +1 -1
  83. package/dist/index.d.mts +477 -0
  84. package/dist/index.d.ts +477 -0
  85. package/dist/index.mjs +22 -18
  86. package/dist/index.mjs.map +1 -1
  87. package/dist/integration-api-CHT2OKAf.d.mts +93 -0
  88. package/dist/integration-api-CHT2OKAf.d.ts +93 -0
  89. package/dist/integrations.d.mts +24 -0
  90. package/dist/integrations.d.ts +24 -0
  91. package/dist/internal/build-runtime.cjs +306 -137
  92. package/dist/internal/build-runtime.cjs.map +1 -1
  93. package/dist/internal/build-runtime.d.mts +41 -0
  94. package/dist/internal/build-runtime.d.ts +41 -0
  95. package/dist/internal/build-runtime.mjs +7 -7
  96. package/dist/internal/client-runtime.d.mts +17 -0
  97. package/dist/internal/client-runtime.d.ts +17 -0
  98. package/dist/internal/config-runtime.cjs +140 -1
  99. package/dist/internal/config-runtime.cjs.map +1 -1
  100. package/dist/internal/config-runtime.d.mts +41 -0
  101. package/dist/internal/config-runtime.d.ts +41 -0
  102. package/dist/internal/config-runtime.mjs +2 -2
  103. package/dist/internal/metadata-image-runtime.d.mts +25 -0
  104. package/dist/internal/metadata-image-runtime.d.ts +25 -0
  105. package/dist/internal/production-node-env.d.mts +12 -0
  106. package/dist/internal/production-node-env.d.ts +12 -0
  107. package/dist/internal/production-runtime.d.mts +44 -0
  108. package/dist/internal/production-runtime.d.ts +44 -0
  109. package/dist/island-CfGru1MO.d.mts +9 -0
  110. package/dist/island-CfGru1MO.d.ts +9 -0
  111. package/dist/markdown.d.mts +60 -0
  112. package/dist/markdown.d.ts +60 -0
  113. package/dist/metadata-DmCudMw_.d.mts +22 -0
  114. package/dist/metadata-xghtOlbR.d.ts +22 -0
  115. package/dist/middleware.cjs +116 -98
  116. package/dist/middleware.cjs.map +1 -1
  117. package/dist/middleware.d.mts +171 -0
  118. package/dist/middleware.d.ts +171 -0
  119. package/dist/middleware.mjs +5 -2
  120. package/dist/navigation-errors-Dvwpzaer.d.mts +13 -0
  121. package/dist/navigation-errors-Dvwpzaer.d.ts +13 -0
  122. package/dist/navigation.d.mts +14 -0
  123. package/dist/navigation.d.ts +14 -0
  124. package/dist/observability.d.mts +335 -0
  125. package/dist/observability.d.ts +335 -0
  126. package/dist/params-BALtrRim.d.ts +15 -0
  127. package/dist/params-ry-lxqmy.d.mts +15 -0
  128. package/dist/plugin-BJDf43dc.d.mts +165 -0
  129. package/dist/plugin-BJDf43dc.d.ts +165 -0
  130. package/dist/plugin.cjs +132 -0
  131. package/dist/plugin.cjs.map +1 -1
  132. package/dist/plugin.d.mts +24 -0
  133. package/dist/plugin.d.ts +24 -0
  134. package/dist/plugin.mjs +4 -4
  135. package/dist/production-runtime-BLxSv9cU.d.ts +79 -0
  136. package/dist/production-runtime-DFN2_RXq.d.mts +79 -0
  137. package/dist/query/client.d.mts +61 -0
  138. package/dist/query/client.d.ts +61 -0
  139. package/dist/query/index.d.mts +90 -0
  140. package/dist/query/index.d.ts +90 -0
  141. package/dist/query/parsers.d.mts +25 -0
  142. package/dist/query/parsers.d.ts +25 -0
  143. package/dist/query/server.d.mts +55 -0
  144. package/dist/query/server.d.ts +55 -0
  145. package/dist/request-Cq5d6qmE.d.mts +6 -0
  146. package/dist/request-LoxDW3lp.d.ts +6 -0
  147. package/dist/request.d.mts +25 -0
  148. package/dist/request.d.ts +25 -0
  149. package/dist/resolver-DJqjLMg_.d.mts +14 -0
  150. package/dist/resolver-IH4RmPEl.d.ts +14 -0
  151. package/dist/route-runtime-DoOHzCAD.d.mts +38 -0
  152. package/dist/route-runtime-DoOHzCAD.d.ts +38 -0
  153. package/dist/router.d.mts +36 -0
  154. package/dist/router.d.ts +36 -0
  155. package/dist/routes.d.mts +226 -0
  156. package/dist/routes.d.ts +226 -0
  157. package/dist/runtime-BA9TOSu1.d.mts +231 -0
  158. package/dist/runtime-Cxpq6xZN.d.mts +27 -0
  159. package/dist/runtime-DTAQ2HDv.d.ts +231 -0
  160. package/dist/runtime-bv63eUiO.d.ts +27 -0
  161. package/dist/server-action-security.d.mts +45 -0
  162. package/dist/server-action-security.d.ts +45 -0
  163. package/dist/server-fn-client.d.mts +33 -0
  164. package/dist/server-fn-client.d.ts +33 -0
  165. package/dist/server-fn-error-DDh14a0V.d.mts +26 -0
  166. package/dist/server-fn-error-DDh14a0V.d.ts +26 -0
  167. package/dist/server-fn.d.mts +121 -0
  168. package/dist/server-fn.d.ts +121 -0
  169. package/dist/server-plugins.d.mts +57 -0
  170. package/dist/server-plugins.d.ts +57 -0
  171. package/dist/server-query-client.d.mts +51 -0
  172. package/dist/server-query-client.d.ts +51 -0
  173. package/dist/server-query.d.mts +37 -0
  174. package/dist/server-query.d.ts +37 -0
  175. package/dist/server.cjs +170 -3
  176. package/dist/server.cjs.map +1 -1
  177. package/dist/server.d.mts +51 -0
  178. package/dist/server.d.ts +51 -0
  179. package/dist/server.mjs +6 -6
  180. package/dist/storage.d.mts +52 -0
  181. package/dist/storage.d.ts +52 -0
  182. package/dist/testing.d.mts +103 -0
  183. package/dist/testing.d.ts +103 -0
  184. package/dist/transport-BmbGTXA5.d.mts +49 -0
  185. package/dist/transport-BmbGTXA5.d.ts +49 -0
  186. package/dist/types-BMxWr97v.d.mts +81 -0
  187. package/dist/types-BMxWr97v.d.ts +81 -0
  188. package/dist/types-D1A6-XvH.d.mts +73 -0
  189. package/dist/types-D1A6-XvH.d.ts +73 -0
  190. package/dist/types-DTzm4TCl.d.mts +78 -0
  191. package/dist/types-DTzm4TCl.d.ts +78 -0
  192. package/dist/utils-B6GaYNJL.d.ts +23 -0
  193. package/dist/utils-CKSHiip6.d.mts +23 -0
  194. package/dist/version.cjs +1 -1
  195. package/dist/version.cjs.map +1 -1
  196. package/dist/version.d.mts +3 -0
  197. package/dist/version.d.ts +3 -0
  198. package/dist/version.mjs +1 -1
  199. package/dist/vite.cjs +140 -2
  200. package/dist/vite.cjs.map +1 -1
  201. package/dist/vite.d.mts +24 -0
  202. package/dist/vite.d.ts +24 -0
  203. package/dist/vite.mjs +4 -4
  204. package/dist/workflows.d.mts +110 -0
  205. package/dist/workflows.d.ts +110 -0
  206. package/package.json +1 -1
  207. package/types/middleware.d.ts +36 -11
  208. package/dist/chunk-AN3PQVKH.mjs.map +0 -1
  209. package/dist/chunk-I4CUBGVF.mjs +0 -93
  210. package/dist/chunk-I4CUBGVF.mjs.map +0 -1
  211. package/dist/chunk-OSWV5IJB.mjs.map +0 -1
  212. package/dist/chunk-T2KL7VEL.mjs.map +0 -1
  213. package/dist/chunk-UXUAWNO5.mjs.map +0 -1
  214. /package/dist/{chunk-SLDBGSC3.mjs.map → chunk-JAEAE27K.mjs.map} +0 -0
  215. /package/dist/{devtools-E4YNCY5J.mjs.map → devtools-K2ERKGNI.mjs.map} +0 -0
package/dist/index.cjs CHANGED
@@ -15152,6 +15152,143 @@ var init_preload = __esm({
15152
15152
  }
15153
15153
  });
15154
15154
 
15155
+ // src/security.ts
15156
+ function resolveFarmSecurityConfig(input) {
15157
+ if (input === void 0) return { csp: false };
15158
+ if (!isPlainRecord(input)) {
15159
+ throw new TypeError("security must be an object containing the csp option.");
15160
+ }
15161
+ if (Object.prototype.hasOwnProperty.call(input, "contentSecurityPolicy")) {
15162
+ throw new TypeError(
15163
+ "security.contentSecurityPolicy is not supported. Use security.csp instead."
15164
+ );
15165
+ }
15166
+ const csp = input.csp;
15167
+ if (csp === void 0 || csp === false) return { csp: false };
15168
+ if (typeof csp === "string") {
15169
+ return {
15170
+ csp: {
15171
+ value: validateSerializedCsp(csp),
15172
+ reportOnly: false
15173
+ }
15174
+ };
15175
+ }
15176
+ if (!isPlainRecord(csp)) {
15177
+ throw new TypeError("security.csp must be a policy string, false, or an options object.");
15178
+ }
15179
+ const reportOnly = validateReportOnly(csp.reportOnly);
15180
+ if (Object.prototype.hasOwnProperty.call(csp, "value")) {
15181
+ if (Object.prototype.hasOwnProperty.call(csp, "policy") || Object.prototype.hasOwnProperty.call(csp, "directives")) {
15182
+ throw new TypeError(
15183
+ "Resolved security.csp values cannot include policy or directives options."
15184
+ );
15185
+ }
15186
+ return {
15187
+ csp: {
15188
+ value: validateSerializedCsp(csp.value),
15189
+ reportOnly
15190
+ }
15191
+ };
15192
+ }
15193
+ const { policy, directives } = csp;
15194
+ if (policy !== void 0 && directives !== void 0) {
15195
+ throw new TypeError("security.csp accepts either policy or directives, not both.");
15196
+ }
15197
+ if (policy === void 0 && directives === void 0) {
15198
+ throw new TypeError("security.csp requires a policy string or directives object.");
15199
+ }
15200
+ return {
15201
+ csp: {
15202
+ value: policy !== void 0 ? validateSerializedCsp(policy) : serializeFarmCspDirectives(directives),
15203
+ reportOnly
15204
+ }
15205
+ };
15206
+ }
15207
+ function serializeFarmCspDirectives(directives) {
15208
+ if (!isPlainRecord(directives)) {
15209
+ throw new TypeError("security.csp.directives must be an object.");
15210
+ }
15211
+ const serialized = [];
15212
+ const normalizedNames = /* @__PURE__ */ new Set();
15213
+ for (const [configuredName, configuredValue] of Object.entries(directives)) {
15214
+ if (configuredValue === false || configuredValue === null || configuredValue === void 0) {
15215
+ continue;
15216
+ }
15217
+ const name = normalizeDirectiveName(configuredName);
15218
+ if (normalizedNames.has(name)) {
15219
+ throw new TypeError(`security.csp contains the duplicate directive ${JSON.stringify(name)}.`);
15220
+ }
15221
+ normalizedNames.add(name);
15222
+ const values = configuredValue === true ? [] : (Array.isArray(configuredValue) ? configuredValue : [configuredValue]).map(
15223
+ validateDirectiveValue
15224
+ );
15225
+ serialized.push(values.length > 0 ? `${name} ${values.join(" ")}` : name);
15226
+ }
15227
+ if (serialized.length === 0) {
15228
+ throw new TypeError("security.csp.directives must contain at least one enabled directive.");
15229
+ }
15230
+ return serialized.join("; ");
15231
+ }
15232
+ function getFarmSecurityHeader(security) {
15233
+ if (!security.csp) return void 0;
15234
+ return {
15235
+ key: security.csp.reportOnly ? "Content-Security-Policy-Report-Only" : "Content-Security-Policy",
15236
+ value: security.csp.value
15237
+ };
15238
+ }
15239
+ function normalizeDirectiveName(value) {
15240
+ const name = value.trim().replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
15241
+ if (!/^[a-z][a-z0-9-]*$/.test(name)) {
15242
+ throw new TypeError(`Invalid security.csp directive name: ${JSON.stringify(value)}.`);
15243
+ }
15244
+ return name;
15245
+ }
15246
+ function validateDirectiveValue(value) {
15247
+ if (typeof value !== "string") {
15248
+ throw new TypeError("security.csp directive values must be strings or booleans.");
15249
+ }
15250
+ const normalized = value.trim();
15251
+ if (!normalized || /[;\r\n]/.test(normalized) || normalized.includes("\0")) {
15252
+ throw new TypeError(`Invalid security.csp directive value: ${JSON.stringify(value)}.`);
15253
+ }
15254
+ return normalized;
15255
+ }
15256
+ function validateSerializedCsp(value) {
15257
+ if (typeof value !== "string") {
15258
+ throw new TypeError("security.csp policy must be a non-empty single-line string.");
15259
+ }
15260
+ const normalized = value.trim().replace(/;+$/g, "").trim();
15261
+ if (!normalized || /[\r\n]/.test(normalized) || normalized.includes("\0")) {
15262
+ throw new TypeError("security.csp policy must be a non-empty single-line string.");
15263
+ }
15264
+ return normalized;
15265
+ }
15266
+ function validateReportOnly(value) {
15267
+ if (value === void 0) return false;
15268
+ if (typeof value !== "boolean") {
15269
+ throw new TypeError("security.csp.reportOnly must be a boolean.");
15270
+ }
15271
+ return value;
15272
+ }
15273
+ function isPlainRecord(value) {
15274
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
15275
+ const prototype = Object.getPrototypeOf(value);
15276
+ return prototype === Object.prototype || prototype === null;
15277
+ }
15278
+ var init_security = __esm({
15279
+ "src/security.ts"() {
15280
+ "use strict";
15281
+ __name(resolveFarmSecurityConfig, "resolveFarmSecurityConfig");
15282
+ __name(serializeFarmCspDirectives, "serializeFarmCspDirectives");
15283
+ __name(getFarmSecurityHeader, "getFarmSecurityHeader");
15284
+ __name(normalizeDirectiveName, "normalizeDirectiveName");
15285
+ __name(validateDirectiveValue, "validateDirectiveValue");
15286
+ __name(validateSerializedCsp, "validateSerializedCsp");
15287
+ __name(validateReportOnly, "validateReportOnly");
15288
+ __name(isPlainRecord, "isPlainRecord");
15289
+ }
15290
+ });
15291
+
15155
15292
  // src/app.ts
15156
15293
  function isResolvedDocsConfig(value) {
15157
15294
  return !!value && typeof value === "object" && "enabled" in value && "entry" in value && "config" in value;
@@ -15192,6 +15329,7 @@ var init_app = __esm({
15192
15329
  init_cache();
15193
15330
  init_auth_config();
15194
15331
  init_preload();
15332
+ init_security();
15195
15333
  defaultDocsConfig = {
15196
15334
  enabled: false,
15197
15335
  entry: "/docs",
@@ -15256,6 +15394,7 @@ var init_app = __esm({
15256
15394
  routeRules: normalizeRouteRules(config.routeRules),
15257
15395
  context: config.context || (() => void 0),
15258
15396
  serverActions: resolveServerActionsConfig(config.serverActions),
15397
+ security: resolveFarmSecurityConfig(config.security),
15259
15398
  images: resolveFarmImageConfig(config.images),
15260
15399
  performance: resolveFarmPerformanceConfig(config.performance),
15261
15400
  i18n: isResolvedI18nConfig(config.i18n) ? config.i18n : resolveFarmI18nConfig(config.i18n, {
@@ -18894,7 +19033,7 @@ var init_environment_vite = __esm({
18894
19033
  var version;
18895
19034
  var init_package = __esm({
18896
19035
  "package.json"() {
18897
- version = "0.1.0-beta.16";
19036
+ version = "0.1.0-beta.17";
18898
19037
  }
18899
19038
  });
18900
19039
 
@@ -19655,11 +19794,28 @@ function createFarmClientOptimizeDepsConfig(entries) {
19655
19794
  ...entries?.length ? { entries: [...entries] } : {}
19656
19795
  };
19657
19796
  }
19797
+ function createFarmSourceAlias(projectRoot, srcDir = "src") {
19798
+ return {
19799
+ "@": import_node_path9.default.resolve(projectRoot, srcDir)
19800
+ };
19801
+ }
19658
19802
  function mergeNoExternal(farmValue, userValue) {
19659
19803
  if (farmValue === true || userValue === true) return true;
19660
19804
  const normalize = /* @__PURE__ */ __name((value) => value == null || value === true ? [] : Array.isArray(value) ? value : [value], "normalize");
19661
19805
  return Array.from(/* @__PURE__ */ new Set([...normalize(farmValue), ...normalize(userValue)]));
19662
19806
  }
19807
+ function mergeAlias(farmValue, userValue) {
19808
+ if (!farmValue) return userValue || {};
19809
+ if (!userValue) return farmValue;
19810
+ if (!Array.isArray(farmValue) && !Array.isArray(userValue)) {
19811
+ return {
19812
+ ...farmValue,
19813
+ ...userValue
19814
+ };
19815
+ }
19816
+ const normalize = /* @__PURE__ */ __name((value) => Array.isArray(value) ? [...value] : Object.entries(value).map(([find, replacement]) => ({ find, replacement })), "normalize");
19817
+ return [...normalize(userValue), ...normalize(farmValue)];
19818
+ }
19663
19819
  function mergeFarmViteConfig(farmConfig, userConfig = {}) {
19664
19820
  const noDiscovery = userConfig.optimizeDeps?.noDiscovery ?? farmConfig.optimizeDeps?.noDiscovery;
19665
19821
  const holdUntilCrawlEnd = userConfig.optimizeDeps?.holdUntilCrawlEnd ?? (userConfig.optimizeDeps?.noDiscovery === true ? false : farmConfig.optimizeDeps?.holdUntilCrawlEnd);
@@ -19674,6 +19830,7 @@ function mergeFarmViteConfig(farmConfig, userConfig = {}) {
19674
19830
  resolve: {
19675
19831
  ...farmConfig.resolve,
19676
19832
  ...userConfig.resolve,
19833
+ alias: mergeAlias(farmConfig.resolve?.alias, userConfig.resolve?.alias),
19677
19834
  dedupe: Array.from(
19678
19835
  /* @__PURE__ */ new Set([...farmConfig.resolve?.dedupe || [], ...userConfig.resolve?.dedupe || []])
19679
19836
  )
@@ -19726,7 +19883,9 @@ var init_vite_config = __esm({
19726
19883
  ];
19727
19884
  __name(createFarmClientOptimizeDepsEntries, "createFarmClientOptimizeDepsEntries");
19728
19885
  __name(createFarmClientOptimizeDepsConfig, "createFarmClientOptimizeDepsConfig");
19886
+ __name(createFarmSourceAlias, "createFarmSourceAlias");
19729
19887
  __name(mergeNoExternal, "mergeNoExternal");
19888
+ __name(mergeAlias, "mergeAlias");
19730
19889
  __name(mergeFarmViteConfig, "mergeFarmViteConfig");
19731
19890
  }
19732
19891
  });
@@ -23686,6 +23845,8 @@ async function resolveConfig(userConfig, mode) {
23686
23845
  const routeRules = normalizeRouteRules(userConfig.routeRules);
23687
23846
  const routeRuleRedirects = routeRulesToRedirects(routeRules);
23688
23847
  const routeRuleHeaders = routeRulesToHeaders(routeRules);
23848
+ const security = resolveFarmSecurityConfig(userConfig.security);
23849
+ const securityHeader = getFarmSecurityHeader(security);
23689
23850
  const deploy = resolveDeployConfig(userConfig);
23690
23851
  const root = userConfig.root || process.cwd();
23691
23852
  const srcDir = userConfig.srcDir || "src";
@@ -23741,7 +23902,11 @@ async function resolveConfig(userConfig, mode) {
23741
23902
  trailingSlash: userConfig.trailingSlash ?? false,
23742
23903
  redirects: /* @__PURE__ */ __name(() => [...redirects, ...routeRuleRedirects], "redirects"),
23743
23904
  rewrites: /* @__PURE__ */ __name(() => rewrites, "rewrites"),
23744
- headers: /* @__PURE__ */ __name(() => [...headers2, ...routeRuleHeaders], "headers"),
23905
+ headers: /* @__PURE__ */ __name(() => [
23906
+ ...headers2,
23907
+ ...routeRuleHeaders,
23908
+ ...securityHeader ? [{ source: "/*", headers: [securityHeader] }] : []
23909
+ ], "headers"),
23745
23910
  routeRules,
23746
23911
  images: resolveFarmImageConfig(userConfig.images),
23747
23912
  performance: resolveFarmPerformanceConfig(userConfig.performance),
@@ -23760,6 +23925,7 @@ async function resolveConfig(userConfig, mode) {
23760
23925
  notFound: userConfig.notFound || {},
23761
23926
  context: userConfig.context || (() => void 0),
23762
23927
  serverActions: resolveServerActionsConfig(userConfig.serverActions),
23928
+ security,
23763
23929
  deploymentId,
23764
23930
  output: userConfig.output || "standalone",
23765
23931
  distDir: userConfig.distDir || ".farm",
@@ -23839,6 +24005,7 @@ var init_config2 = __esm({
23839
24005
  init_config();
23840
24006
  init_auth_config();
23841
24007
  init_preload();
24008
+ init_security();
23842
24009
  init_config_entry();
23843
24010
  FARM_RESOLVED_CUSTOM_CONTEXT = /* @__PURE__ */ Symbol.for("farm.resolvedCustomContext");
23844
24011
  __name(hasCustomFarmRouteContext, "hasCustomFarmRouteContext");
@@ -30673,7 +30840,7 @@ async function defineConfig2(config = {}) {
30673
30840
  // Stub out problematic server-only modules during dev mode
30674
30841
  alias: {
30675
30842
  ...getFarmLayerAliases(config.layers),
30676
- "@": path25.resolve(appRoot, "src"),
30843
+ ...createFarmSourceAlias(appRoot, config.srcDir),
30677
30844
  // Nitro internals that should not be resolved in browser
30678
30845
  "supports-color": "data:text/javascript,export default false; export const supportsColor = false; export const stdout = false; export const stderr = false;",
30679
30846
  "@poppinss/dumper": "data:text/javascript,export default {};",
@@ -32139,6 +32306,7 @@ __export(src_exports, {
32139
32306
  ServerActionError: () => ServerActionError,
32140
32307
  ServerActionRequestError: () => ServerActionRequestError,
32141
32308
  ServerFnFailure: () => ServerFnFailure,
32309
+ UnsupportedRateLimitStorageError: () => UnsupportedRateLimitStorageError,
32142
32310
  _parseServerFnSchema: () => _parseServerFnSchema,
32143
32311
  _runWithAfterNodeResponse: () => _runWithAfterNodeResponse,
32144
32312
  _runWithAfterRequest: () => _runWithAfterRequest,
@@ -32363,6 +32531,7 @@ __export(src_exports, {
32363
32531
  matchRegisteredIntegrationRoute: () => matchRegisteredIntegrationRoute,
32364
32532
  matchRoute: () => matchRoute,
32365
32533
  matchSSGPage: () => matchSSGPage,
32534
+ memoryRateLimitStorage: () => memoryRateLimitStorage,
32366
32535
  memoryStorage: () => memoryStorage,
32367
32536
  mergeFarmRouteRuntimeConfigs: () => mergeFarmRouteRuntimeConfigs,
32368
32537
  mergeScheduledTasks: () => mergeScheduledTasks,
@@ -34819,35 +34988,69 @@ function parseRouteParams(input, parsers, options = {}) {
34819
34988
  __name(parseRouteParams, "parseRouteParams");
34820
34989
 
34821
34990
  // src/middleware/chain.ts
34822
- init_storage();
34823
- function getRateLimitStorage() {
34824
- return getStorage("ratelimit");
34825
- }
34826
- __name(getRateLimitStorage, "getRateLimitStorage");
34827
- var defaultRateLimitStorage = {
34828
- async get(key) {
34829
- const storage = getRateLimitStorage();
34830
- const value = await storage.getItem(key);
34831
- return value ?? null;
34832
- },
34833
- async set(key, value, ttl) {
34834
- const storage = getRateLimitStorage();
34835
- await storage.setItem(key, value, ttl ? { ttl } : void 0);
34836
- },
34837
- async delete(key) {
34838
- const storage = getRateLimitStorage();
34839
- await storage.removeItem(key);
34840
- },
34841
- async ttl(key) {
34842
- const storage = getRateLimitStorage();
34843
- const record = await storage.getItem(key);
34844
- if (!record || !record.resetAt) {
34991
+ var DEFAULT_MEMORY_RATE_LIMIT_ENTRIES = 1e5;
34992
+ var _UnsupportedRateLimitStorageError = class _UnsupportedRateLimitStorageError extends TypeError {
34993
+ constructor() {
34994
+ super(
34995
+ "RateLimitStorage must implement atomic increment(key, windowMs). Legacy get/set adapters can lose increments under concurrency. Use memoryRateLimitStorage() for one process or redisRateLimitStorage() from @farm.js/cache-redis for production."
34996
+ );
34997
+ this.name = "UnsupportedRateLimitStorageError";
34998
+ }
34999
+ };
35000
+ __name(_UnsupportedRateLimitStorageError, "UnsupportedRateLimitStorageError");
35001
+ var UnsupportedRateLimitStorageError = _UnsupportedRateLimitStorageError;
35002
+ function memoryRateLimitStorage(options = {}) {
35003
+ const maxEntries = options.maxEntries ?? DEFAULT_MEMORY_RATE_LIMIT_ENTRIES;
35004
+ if (!Number.isSafeInteger(maxEntries) || maxEntries <= 0) {
35005
+ throw new TypeError("memoryRateLimitStorage maxEntries must be a positive safe integer.");
35006
+ }
35007
+ const records = /* @__PURE__ */ new Map();
35008
+ function read(key, now2) {
35009
+ const record = records.get(key);
35010
+ if (!record) return null;
35011
+ if (record.resetAt <= now2) {
35012
+ records.delete(key);
34845
35013
  return null;
34846
35014
  }
34847
- const remainingMs = record.resetAt - Date.now();
34848
- return remainingMs > 0 ? Math.ceil(remainingMs / 1e3) : null;
35015
+ return record;
34849
35016
  }
34850
- };
35017
+ __name(read, "read");
35018
+ function pruneExpired(now2) {
35019
+ for (const [key, record] of records) {
35020
+ if (record.resetAt <= now2) records.delete(key);
35021
+ }
35022
+ }
35023
+ __name(pruneExpired, "pruneExpired");
35024
+ return {
35025
+ increment(key, windowMs) {
35026
+ if (!Number.isSafeInteger(windowMs) || windowMs <= 0) {
35027
+ throw new TypeError("Rate-limit windowMs must be a positive safe integer.");
35028
+ }
35029
+ const now2 = Date.now();
35030
+ const current = read(key, now2);
35031
+ if (current) {
35032
+ const next2 = { count: current.count + 1, resetAt: current.resetAt };
35033
+ records.set(key, next2);
35034
+ return next2;
35035
+ }
35036
+ if (records.size >= maxEntries) pruneExpired(now2);
35037
+ if (records.size >= maxEntries) {
35038
+ throw new Error(
35039
+ `Process-local rate-limit storage reached its ${maxEntries} active-key capacity. Configure a shared production adapter or increase maxEntries.`
35040
+ );
35041
+ }
35042
+ const next = { count: 1, resetAt: now2 + windowMs };
35043
+ records.set(key, next);
35044
+ return next;
35045
+ },
35046
+ get(key) {
35047
+ const record = read(key, Date.now());
35048
+ return record ? { ...record } : null;
35049
+ }
35050
+ };
35051
+ }
35052
+ __name(memoryRateLimitStorage, "memoryRateLimitStorage");
35053
+ var defaultRateLimitStorage = memoryRateLimitStorage();
34851
35054
  function parseTimeWindow(window2) {
34852
35055
  const match = window2.match(/^(\d+)(ms|s|m|h|d)$/);
34853
35056
  if (!match) throw new Error(`Invalid time window: ${window2}`);
@@ -34860,52 +35063,73 @@ function parseTimeWindow(window2) {
34860
35063
  h: 60 * 60 * 1e3,
34861
35064
  d: 24 * 60 * 60 * 1e3
34862
35065
  };
34863
- return value * multipliers[unit];
35066
+ const windowMs = value * multipliers[unit];
35067
+ if (!Number.isSafeInteger(windowMs) || windowMs <= 0) {
35068
+ throw new Error(`Invalid time window: ${window2}`);
35069
+ }
35070
+ return windowMs;
34864
35071
  }
34865
35072
  __name(parseTimeWindow, "parseTimeWindow");
34866
35073
  function createRateLimitMiddleware(config) {
35074
+ if (!Number.isSafeInteger(config.requests) || config.requests <= 0) {
35075
+ throw new TypeError("Rate limit requests must be a positive safe integer.");
35076
+ }
34867
35077
  const windowMs = parseTimeWindow(config.window);
34868
35078
  const storage = config.storage || defaultRateLimitStorage;
35079
+ assertAtomicRateLimitStorage(storage);
34869
35080
  return async (ctx, next) => {
34870
35081
  const key = config.keyGenerator ? config.keyGenerator(ctx) : `${ctx.request.socket.remoteAddress}:${ctx.pathname}`;
35082
+ const current = await storage.increment(key, windowMs);
35083
+ assertRateLimitIncrementResult(current);
34871
35084
  const now2 = Date.now();
34872
- const ttlSeconds = Math.ceil(windowMs / 1e3);
34873
- const record = await storage.get(key);
34874
- if (record && now2 > record.resetAt) {
34875
- await storage.delete(key);
34876
- }
34877
- const current = await storage.get(key);
34878
- if (!current) {
34879
- await storage.set(
34880
- key,
34881
- {
34882
- count: 1,
34883
- resetAt: now2 + windowMs
34884
- },
34885
- ttlSeconds
34886
- );
34887
- return next();
34888
- }
34889
- if (current.count >= config.requests) {
35085
+ const resetIn = Math.max(1, Math.ceil((current.resetAt - now2) / 1e3));
35086
+ const remaining = Math.max(0, config.requests - current.count);
35087
+ setRateLimitHeaders(ctx, config.requests, remaining, resetIn, Math.ceil(windowMs / 1e3));
35088
+ if (current.count > config.requests) {
35089
+ setMiddlewareResponseHeader(ctx, "Retry-After", String(resetIn));
34890
35090
  if (config.onLimit) {
34891
35091
  const result = await config.onLimit(ctx);
34892
- if (result) return;
35092
+ if (result) return result;
34893
35093
  }
34894
35094
  ctx.json(
34895
35095
  {
34896
35096
  error: "Rate limit exceeded",
34897
- retryAfter: Math.ceil((current.resetAt - now2) / 1e3)
35097
+ retryAfter: resetIn
34898
35098
  },
34899
35099
  429
34900
35100
  );
34901
35101
  return;
34902
35102
  }
34903
- current.count++;
34904
- await storage.set(key, current, ttlSeconds);
34905
35103
  return next();
34906
35104
  };
34907
35105
  }
34908
35106
  __name(createRateLimitMiddleware, "createRateLimitMiddleware");
35107
+ function assertAtomicRateLimitStorage(storage) {
35108
+ if (!storage || typeof storage.increment !== "function") {
35109
+ throw new UnsupportedRateLimitStorageError();
35110
+ }
35111
+ }
35112
+ __name(assertAtomicRateLimitStorage, "assertAtomicRateLimitStorage");
35113
+ function assertRateLimitIncrementResult(result) {
35114
+ if (!result || !Number.isSafeInteger(result.count) || result.count <= 0 || !Number.isFinite(result.resetAt) || result.resetAt <= 0) {
35115
+ throw new TypeError(
35116
+ "RateLimitStorage.increment() must return a positive integer count and a resetAt timestamp."
35117
+ );
35118
+ }
35119
+ }
35120
+ __name(assertRateLimitIncrementResult, "assertRateLimitIncrementResult");
35121
+ function setRateLimitHeaders(ctx, limit, remaining, resetIn, windowSeconds) {
35122
+ setMiddlewareResponseHeader(ctx, "RateLimit-Policy", `"farm";q=${limit};w=${windowSeconds}`);
35123
+ setMiddlewareResponseHeader(ctx, "RateLimit", `"farm";r=${remaining};t=${resetIn}`);
35124
+ }
35125
+ __name(setRateLimitHeaders, "setRateLimitHeaders");
35126
+ function setMiddlewareResponseHeader(ctx, name, value) {
35127
+ ctx.headers.set(name, value);
35128
+ if (!ctx.response.headersSent && !ctx.response.writableEnded) {
35129
+ ctx.response.setHeader(name, value);
35130
+ }
35131
+ }
35132
+ __name(setMiddlewareResponseHeader, "setMiddlewareResponseHeader");
34909
35133
  function matchPattern(pattern, pathname) {
34910
35134
  if (pattern instanceof RegExp) {
34911
35135
  return pattern.test(pathname);
@@ -35055,6 +35279,15 @@ var _MiddlewareChainImpl = class _MiddlewareChainImpl {
35055
35279
  __name(_MiddlewareChainImpl, "MiddlewareChainImpl");
35056
35280
  var MiddlewareChainImpl = _MiddlewareChainImpl;
35057
35281
  async function getRateLimitStatus(key, limit, storage = defaultRateLimitStorage) {
35282
+ if (!Number.isSafeInteger(limit) || limit <= 0) {
35283
+ throw new TypeError("Rate limit must be a positive safe integer.");
35284
+ }
35285
+ assertAtomicRateLimitStorage(storage);
35286
+ if (typeof storage.get !== "function") {
35287
+ throw new TypeError(
35288
+ "getRateLimitStatus() requires a RateLimitStorage adapter that implements get(key)."
35289
+ );
35290
+ }
35058
35291
  const record = await storage.get(key);
35059
35292
  if (!record) {
35060
35293
  return {
@@ -35066,6 +35299,7 @@ async function getRateLimitStatus(key, limit, storage = defaultRateLimitStorage)
35066
35299
  isLimited: false
35067
35300
  };
35068
35301
  }
35302
+ assertRateLimitIncrementResult(record);
35069
35303
  const now2 = Date.now();
35070
35304
  if (record.resetAt && now2 > record.resetAt) {
35071
35305
  return {
@@ -35086,9 +35320,6 @@ async function getRateLimitStatus(key, limit, storage = defaultRateLimitStorage)
35086
35320
  const remainingMs = record.resetAt - now2;
35087
35321
  resetIn = remainingMs > 0 ? Math.ceil(remainingMs / 1e3) : null;
35088
35322
  resetAt = new Date(record.resetAt);
35089
- } else if (storage.ttl) {
35090
- resetIn = await storage.ttl(key);
35091
- resetAt = resetIn ? new Date(now2 + resetIn * 1e3) : null;
35092
35323
  }
35093
35324
  return {
35094
35325
  requests,
@@ -37051,6 +37282,7 @@ __name(withVite5TransformContext, "withVite5TransformContext");
37051
37282
 
37052
37283
  // src/nitro/universal-build.ts
37053
37284
  init_font_vite();
37285
+ init_vite_config();
37054
37286
  var import_meta = {};
37055
37287
  function preloadFarmNitroRuntime() {
37056
37288
  return import("nitro").then(
@@ -39444,9 +39676,7 @@ async function buildSSRInMemory(productionVite, config, root, routeManager, apiR
39444
39676
  postcss: postcssConfigDir
39445
39677
  } : void 0,
39446
39678
  resolve: {
39447
- alias: {
39448
- "@": import_path12.default.resolve(root, "src")
39449
- },
39679
+ alias: createFarmSourceAlias(root, config.srcDir),
39450
39680
  // Programmatic route wrappers are created inside @farm.js/core. Resolve
39451
39681
  // their React imports from the application so React 18/19 elements and
39452
39682
  // the selected server renderer always share the same runtime instance.
@@ -43104,6 +43334,9 @@ async function createProjectModuleServer(createViteServer, config, root) {
43104
43334
  middlewareMode: true,
43105
43335
  hmr: false
43106
43336
  },
43337
+ resolve: {
43338
+ alias: createFarmSourceAlias(root, config.srcDir)
43339
+ },
43107
43340
  optimizeDeps: {
43108
43341
  noDiscovery: true
43109
43342
  },
@@ -44800,6 +45033,7 @@ __name(decodeCookiePart, "decodeCookiePart");
44800
45033
  ServerActionError,
44801
45034
  ServerActionRequestError,
44802
45035
  ServerFnFailure,
45036
+ UnsupportedRateLimitStorageError,
44803
45037
  _parseServerFnSchema,
44804
45038
  _runWithAfterNodeResponse,
44805
45039
  _runWithAfterRequest,
@@ -45024,6 +45258,7 @@ __name(decodeCookiePart, "decodeCookiePart");
45024
45258
  matchRegisteredIntegrationRoute,
45025
45259
  matchRoute,
45026
45260
  matchSSGPage,
45261
+ memoryRateLimitStorage,
45027
45262
  memoryStorage,
45028
45263
  mergeFarmRouteRuntimeConfigs,
45029
45264
  mergeScheduledTasks,