@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
@@ -0,0 +1,227 @@
1
+ import {
2
+ __name
3
+ } from "./chunk-CGILA3WO.mjs";
4
+
5
+ // src/auth-config.ts
6
+ import { createRequire } from "module";
7
+ import path from "path";
8
+ import { pathToFileURL } from "url";
9
+ function resolveFarmAuthConfig(input) {
10
+ const config = input === true ? {} : input && typeof input === "object" ? input : {};
11
+ const passwordConfig = typeof config.emailAndPassword === "object" ? config.emailAndPassword : {};
12
+ const resolved = {
13
+ enabled: input !== void 0 && input !== false && config.enabled !== false,
14
+ appName: config.appName,
15
+ basePath: normalizeBasePath(config.basePath),
16
+ emailAndPassword: {
17
+ enabled: config.emailAndPassword !== false,
18
+ requireEmailVerification: passwordConfig.requireEmailVerification ?? false,
19
+ minPasswordLength: passwordConfig.minPasswordLength ?? 8,
20
+ maxPasswordLength: passwordConfig.maxPasswordLength ?? 128
21
+ },
22
+ session: {
23
+ expiresIn: config.session?.expiresIn ?? 60 * 60 * 24 * 7,
24
+ updateAge: config.session?.updateAge ?? 60 * 60 * 24
25
+ },
26
+ database: {
27
+ url: config.database?.url,
28
+ path: config.database?.path || ".farm/auth.sqlite",
29
+ migrateInDevelopment: config.database?.migrateInDevelopment ?? true
30
+ }
31
+ };
32
+ validateFarmAuthConfig(resolved);
33
+ return resolved;
34
+ }
35
+ __name(resolveFarmAuthConfig, "resolveFarmAuthConfig");
36
+ async function resolveFarmAuthIntegration(config, options) {
37
+ if (!config.enabled) return void 0;
38
+ const root = path.resolve(options.root);
39
+ let modulePath;
40
+ try {
41
+ const resolveFromApp = createRequire(path.join(root, "package.json"));
42
+ modulePath = resolveFromApp.resolve("@farm.js/auth/internal");
43
+ } catch {
44
+ throw new Error(
45
+ "The `auth` config requires @farm.js/auth. Install it with `pnpm add @farm.js/auth` and try again."
46
+ );
47
+ }
48
+ const runtime = await import(
49
+ /* @vite-ignore */
50
+ pathToFileURL(modulePath).href
51
+ );
52
+ if (typeof runtime.createFarmAuthIntegration !== "function") {
53
+ throw new Error(
54
+ "The installed @farm.js/auth package is incompatible with this version of @farm.js/core."
55
+ );
56
+ }
57
+ return runtime.createFarmAuthIntegration(config, {
58
+ ...options,
59
+ root
60
+ });
61
+ }
62
+ __name(resolveFarmAuthIntegration, "resolveFarmAuthIntegration");
63
+ function normalizeBasePath(value) {
64
+ const route = (value || "/api/auth").trim();
65
+ const withLeadingSlash = route.startsWith("/") ? route : `/${route}`;
66
+ const normalized = withLeadingSlash.replace(/\/+/g, "/").replace(/\/+$/, "");
67
+ return normalized || "/api/auth";
68
+ }
69
+ __name(normalizeBasePath, "normalizeBasePath");
70
+ function validateFarmAuthConfig(config) {
71
+ const { minPasswordLength, maxPasswordLength } = config.emailAndPassword;
72
+ if (!Number.isInteger(minPasswordLength) || minPasswordLength < 1) {
73
+ throw new Error("auth.emailAndPassword.minPasswordLength must be a positive integer.");
74
+ }
75
+ if (!Number.isInteger(maxPasswordLength) || maxPasswordLength < minPasswordLength) {
76
+ throw new Error(
77
+ "auth.emailAndPassword.maxPasswordLength must be an integer greater than or equal to minPasswordLength."
78
+ );
79
+ }
80
+ if (!Number.isInteger(config.session.expiresIn) || config.session.expiresIn < 1) {
81
+ throw new Error("auth.session.expiresIn must be a positive integer.");
82
+ }
83
+ if (!Number.isInteger(config.session.updateAge) || config.session.updateAge < 0) {
84
+ throw new Error("auth.session.updateAge must be a non-negative integer.");
85
+ }
86
+ }
87
+ __name(validateFarmAuthConfig, "validateFarmAuthConfig");
88
+
89
+ // src/security.ts
90
+ function resolveFarmSecurityConfig(input) {
91
+ if (input === void 0) return { csp: false };
92
+ if (!isPlainRecord(input)) {
93
+ throw new TypeError("security must be an object containing the csp option.");
94
+ }
95
+ if (Object.prototype.hasOwnProperty.call(input, "contentSecurityPolicy")) {
96
+ throw new TypeError(
97
+ "security.contentSecurityPolicy is not supported. Use security.csp instead."
98
+ );
99
+ }
100
+ const csp = input.csp;
101
+ if (csp === void 0 || csp === false) return { csp: false };
102
+ if (typeof csp === "string") {
103
+ return {
104
+ csp: {
105
+ value: validateSerializedCsp(csp),
106
+ reportOnly: false
107
+ }
108
+ };
109
+ }
110
+ if (!isPlainRecord(csp)) {
111
+ throw new TypeError("security.csp must be a policy string, false, or an options object.");
112
+ }
113
+ const reportOnly = validateReportOnly(csp.reportOnly);
114
+ if (Object.prototype.hasOwnProperty.call(csp, "value")) {
115
+ if (Object.prototype.hasOwnProperty.call(csp, "policy") || Object.prototype.hasOwnProperty.call(csp, "directives")) {
116
+ throw new TypeError(
117
+ "Resolved security.csp values cannot include policy or directives options."
118
+ );
119
+ }
120
+ return {
121
+ csp: {
122
+ value: validateSerializedCsp(csp.value),
123
+ reportOnly
124
+ }
125
+ };
126
+ }
127
+ const { policy, directives } = csp;
128
+ if (policy !== void 0 && directives !== void 0) {
129
+ throw new TypeError("security.csp accepts either policy or directives, not both.");
130
+ }
131
+ if (policy === void 0 && directives === void 0) {
132
+ throw new TypeError("security.csp requires a policy string or directives object.");
133
+ }
134
+ return {
135
+ csp: {
136
+ value: policy !== void 0 ? validateSerializedCsp(policy) : serializeFarmCspDirectives(directives),
137
+ reportOnly
138
+ }
139
+ };
140
+ }
141
+ __name(resolveFarmSecurityConfig, "resolveFarmSecurityConfig");
142
+ function serializeFarmCspDirectives(directives) {
143
+ if (!isPlainRecord(directives)) {
144
+ throw new TypeError("security.csp.directives must be an object.");
145
+ }
146
+ const serialized = [];
147
+ const normalizedNames = /* @__PURE__ */ new Set();
148
+ for (const [configuredName, configuredValue] of Object.entries(directives)) {
149
+ if (configuredValue === false || configuredValue === null || configuredValue === void 0) {
150
+ continue;
151
+ }
152
+ const name = normalizeDirectiveName(configuredName);
153
+ if (normalizedNames.has(name)) {
154
+ throw new TypeError(`security.csp contains the duplicate directive ${JSON.stringify(name)}.`);
155
+ }
156
+ normalizedNames.add(name);
157
+ const values = configuredValue === true ? [] : (Array.isArray(configuredValue) ? configuredValue : [configuredValue]).map(
158
+ validateDirectiveValue
159
+ );
160
+ serialized.push(values.length > 0 ? `${name} ${values.join(" ")}` : name);
161
+ }
162
+ if (serialized.length === 0) {
163
+ throw new TypeError("security.csp.directives must contain at least one enabled directive.");
164
+ }
165
+ return serialized.join("; ");
166
+ }
167
+ __name(serializeFarmCspDirectives, "serializeFarmCspDirectives");
168
+ function getFarmSecurityHeader(security) {
169
+ if (!security.csp) return void 0;
170
+ return {
171
+ key: security.csp.reportOnly ? "Content-Security-Policy-Report-Only" : "Content-Security-Policy",
172
+ value: security.csp.value
173
+ };
174
+ }
175
+ __name(getFarmSecurityHeader, "getFarmSecurityHeader");
176
+ function normalizeDirectiveName(value) {
177
+ const name = value.trim().replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
178
+ if (!/^[a-z][a-z0-9-]*$/.test(name)) {
179
+ throw new TypeError(`Invalid security.csp directive name: ${JSON.stringify(value)}.`);
180
+ }
181
+ return name;
182
+ }
183
+ __name(normalizeDirectiveName, "normalizeDirectiveName");
184
+ function validateDirectiveValue(value) {
185
+ if (typeof value !== "string") {
186
+ throw new TypeError("security.csp directive values must be strings or booleans.");
187
+ }
188
+ const normalized = value.trim();
189
+ if (!normalized || /[;\r\n]/.test(normalized) || normalized.includes("\0")) {
190
+ throw new TypeError(`Invalid security.csp directive value: ${JSON.stringify(value)}.`);
191
+ }
192
+ return normalized;
193
+ }
194
+ __name(validateDirectiveValue, "validateDirectiveValue");
195
+ function validateSerializedCsp(value) {
196
+ if (typeof value !== "string") {
197
+ throw new TypeError("security.csp policy must be a non-empty single-line string.");
198
+ }
199
+ const normalized = value.trim().replace(/;+$/g, "").trim();
200
+ if (!normalized || /[\r\n]/.test(normalized) || normalized.includes("\0")) {
201
+ throw new TypeError("security.csp policy must be a non-empty single-line string.");
202
+ }
203
+ return normalized;
204
+ }
205
+ __name(validateSerializedCsp, "validateSerializedCsp");
206
+ function validateReportOnly(value) {
207
+ if (value === void 0) return false;
208
+ if (typeof value !== "boolean") {
209
+ throw new TypeError("security.csp.reportOnly must be a boolean.");
210
+ }
211
+ return value;
212
+ }
213
+ __name(validateReportOnly, "validateReportOnly");
214
+ function isPlainRecord(value) {
215
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
216
+ const prototype = Object.getPrototypeOf(value);
217
+ return prototype === Object.prototype || prototype === null;
218
+ }
219
+ __name(isPlainRecord, "isPlainRecord");
220
+
221
+ export {
222
+ resolveFarmAuthConfig,
223
+ resolveFarmAuthIntegration,
224
+ resolveFarmSecurityConfig,
225
+ getFarmSecurityHeader
226
+ };
227
+ //# sourceMappingURL=chunk-E257KFBU.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/auth-config.ts","../src/security.ts"],"sourcesContent":["import { createRequire } from \"node:module\";\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport type { FarmIntegration } from \"./integrations\";\n\nexport interface FarmAuthEmailAndPasswordConfig {\n /** Require a verified email before creating a session. @default false */\n requireEmailVerification?: boolean;\n /** Smallest accepted password length. @default 8 */\n minPasswordLength?: number;\n /** Largest accepted password length. @default 128 */\n maxPasswordLength?: number;\n}\n\nexport interface FarmAuthSessionConfig {\n /** Session lifetime in seconds. @default 604800 */\n expiresIn?: number;\n /** Session refresh interval in seconds. @default 86400 */\n updateAge?: number;\n}\n\nexport interface FarmAuthDatabaseConfig {\n /**\n * Postgres connection string. Defaults to DATABASE_URL.\n * Local development falls back to SQLite when no URL is present.\n */\n url?: string;\n /** Local SQLite path. @default \".farm/auth.sqlite\" */\n path?: string;\n /** Automatically update the auth schema in development. @default true */\n migrateInDevelopment?: boolean;\n}\n\nexport interface FarmAuthConfig {\n /** Set false to disable auth without removing its configuration. @default true */\n enabled?: boolean;\n /** Display name used by authentication emails and metadata. */\n appName?: string;\n /** Route prefix for the auth endpoints. @default \"/api/auth\" */\n basePath?: string;\n /**\n * Email/password authentication. It is enabled by default; set false to\n * disable it when adding another sign-in method.\n */\n emailAndPassword?: boolean | FarmAuthEmailAndPasswordConfig;\n session?: FarmAuthSessionConfig;\n database?: FarmAuthDatabaseConfig;\n}\n\nexport type FarmAuthUserConfig = boolean | FarmAuthConfig;\n\nexport interface ResolvedFarmAuthConfig {\n enabled: boolean;\n appName?: string;\n basePath: string;\n emailAndPassword: {\n enabled: boolean;\n requireEmailVerification: boolean;\n minPasswordLength: number;\n maxPasswordLength: number;\n };\n session: {\n expiresIn: number;\n updateAge: number;\n };\n database: {\n url?: string;\n path: string;\n migrateInDevelopment: boolean;\n };\n}\n\ninterface FarmAuthRuntimeModule {\n createFarmAuthIntegration(\n config: ResolvedFarmAuthConfig,\n options: {\n root: string;\n mode: \"development\" | \"production\";\n },\n ): FarmIntegration;\n}\n\nexport function resolveFarmAuthConfig(\n input: FarmAuthUserConfig | undefined,\n): ResolvedFarmAuthConfig {\n const config = input === true ? {} : input && typeof input === \"object\" ? input : {};\n const passwordConfig = typeof config.emailAndPassword === \"object\" ? config.emailAndPassword : {};\n\n const resolved: ResolvedFarmAuthConfig = {\n enabled: input !== undefined && input !== false && config.enabled !== false,\n appName: config.appName,\n basePath: normalizeBasePath(config.basePath),\n emailAndPassword: {\n enabled: config.emailAndPassword !== false,\n requireEmailVerification: passwordConfig.requireEmailVerification ?? false,\n minPasswordLength: passwordConfig.minPasswordLength ?? 8,\n maxPasswordLength: passwordConfig.maxPasswordLength ?? 128,\n },\n session: {\n expiresIn: config.session?.expiresIn ?? 60 * 60 * 24 * 7,\n updateAge: config.session?.updateAge ?? 60 * 60 * 24,\n },\n database: {\n url: config.database?.url,\n path: config.database?.path || \".farm/auth.sqlite\",\n migrateInDevelopment: config.database?.migrateInDevelopment ?? true,\n },\n };\n\n validateFarmAuthConfig(resolved);\n return resolved;\n}\n\nexport async function resolveFarmAuthIntegration(\n config: ResolvedFarmAuthConfig,\n options: {\n root: string;\n mode: \"development\" | \"production\";\n },\n): Promise<FarmIntegration | undefined> {\n if (!config.enabled) return undefined;\n\n const root = path.resolve(options.root);\n let modulePath: string;\n try {\n const resolveFromApp = createRequire(path.join(root, \"package.json\"));\n modulePath = resolveFromApp.resolve(\"@farm.js/auth/internal\");\n } catch {\n throw new Error(\n \"The `auth` config requires @farm.js/auth. Install it with `pnpm add @farm.js/auth` and try again.\",\n );\n }\n\n const runtime = (await import(\n /* @vite-ignore */ pathToFileURL(modulePath).href\n )) as FarmAuthRuntimeModule;\n if (typeof runtime.createFarmAuthIntegration !== \"function\") {\n throw new Error(\n \"The installed @farm.js/auth package is incompatible with this version of @farm.js/core.\",\n );\n }\n\n return runtime.createFarmAuthIntegration(config, {\n ...options,\n root,\n });\n}\n\nfunction normalizeBasePath(value: string | undefined): string {\n const route = (value || \"/api/auth\").trim();\n const withLeadingSlash = route.startsWith(\"/\") ? route : `/${route}`;\n const normalized = withLeadingSlash.replace(/\\/+/g, \"/\").replace(/\\/+$/, \"\");\n return normalized || \"/api/auth\";\n}\n\nfunction validateFarmAuthConfig(config: ResolvedFarmAuthConfig): void {\n const { minPasswordLength, maxPasswordLength } = config.emailAndPassword;\n if (!Number.isInteger(minPasswordLength) || minPasswordLength < 1) {\n throw new Error(\"auth.emailAndPassword.minPasswordLength must be a positive integer.\");\n }\n if (!Number.isInteger(maxPasswordLength) || maxPasswordLength < minPasswordLength) {\n throw new Error(\n \"auth.emailAndPassword.maxPasswordLength must be an integer greater than or equal to minPasswordLength.\",\n );\n }\n if (!Number.isInteger(config.session.expiresIn) || config.session.expiresIn < 1) {\n throw new Error(\"auth.session.expiresIn must be a positive integer.\");\n }\n if (!Number.isInteger(config.session.updateAge) || config.session.updateAge < 0) {\n throw new Error(\"auth.session.updateAge must be a non-negative integer.\");\n }\n}\n","export type FarmCspDirectiveValue = string | readonly string[] | boolean | null | undefined;\n\nexport type FarmCspDirectives = Readonly<Record<string, FarmCspDirectiveValue>>;\n\nexport interface FarmCspOptions {\n /** A pre-serialized CSP value. Cannot be combined with directives. */\n policy?: string;\n /** CSP directives using camelCase or kebab-case names. */\n directives?: FarmCspDirectives;\n /** Emit Content-Security-Policy-Report-Only instead of enforcing the policy. */\n reportOnly?: boolean;\n}\n\nexport type FarmCspConfig = string | FarmCspOptions;\n\nexport interface FarmSecurityConfig {\n /** App-wide Content Security Policy applied to pages, APIs, and static output. */\n csp?: FarmCspConfig | false;\n /** @deprecated Use csp. */\n contentSecurityPolicy?: never;\n}\n\nexport interface ResolvedFarmCspConfig {\n value: string;\n reportOnly: boolean;\n}\n\nexport interface ResolvedFarmSecurityConfig {\n csp: ResolvedFarmCspConfig | false;\n}\n\nexport function resolveFarmSecurityConfig(\n input: FarmSecurityConfig | ResolvedFarmSecurityConfig | undefined,\n): ResolvedFarmSecurityConfig {\n if (input === undefined) return { csp: false };\n if (!isPlainRecord(input)) {\n throw new TypeError(\"security must be an object containing the csp option.\");\n }\n if (Object.prototype.hasOwnProperty.call(input, \"contentSecurityPolicy\")) {\n throw new TypeError(\n \"security.contentSecurityPolicy is not supported. Use security.csp instead.\",\n );\n }\n\n const csp = input.csp;\n if (csp === undefined || csp === false) return { csp: false };\n\n if (typeof csp === \"string\") {\n return {\n csp: {\n value: validateSerializedCsp(csp),\n reportOnly: false,\n },\n };\n }\n\n if (!isPlainRecord(csp)) {\n throw new TypeError(\"security.csp must be a policy string, false, or an options object.\");\n }\n\n const reportOnly = validateReportOnly(csp.reportOnly);\n if (Object.prototype.hasOwnProperty.call(csp, \"value\")) {\n if (\n Object.prototype.hasOwnProperty.call(csp, \"policy\") ||\n Object.prototype.hasOwnProperty.call(csp, \"directives\")\n ) {\n throw new TypeError(\n \"Resolved security.csp values cannot include policy or directives options.\",\n );\n }\n return {\n csp: {\n value: validateSerializedCsp(csp.value),\n reportOnly,\n },\n };\n }\n\n const { policy, directives } = csp;\n if (policy !== undefined && directives !== undefined) {\n throw new TypeError(\"security.csp accepts either policy or directives, not both.\");\n }\n if (policy === undefined && directives === undefined) {\n throw new TypeError(\"security.csp requires a policy string or directives object.\");\n }\n\n return {\n csp: {\n value:\n policy !== undefined\n ? validateSerializedCsp(policy)\n : serializeFarmCspDirectives(directives as FarmCspDirectives),\n reportOnly,\n },\n };\n}\n\nexport function serializeFarmCspDirectives(directives: FarmCspDirectives): string {\n if (!isPlainRecord(directives)) {\n throw new TypeError(\"security.csp.directives must be an object.\");\n }\n const serialized: string[] = [];\n const normalizedNames = new Set<string>();\n\n for (const [configuredName, configuredValue] of Object.entries(directives)) {\n if (configuredValue === false || configuredValue === null || configuredValue === undefined) {\n continue;\n }\n\n const name = normalizeDirectiveName(configuredName);\n if (normalizedNames.has(name)) {\n throw new TypeError(`security.csp contains the duplicate directive ${JSON.stringify(name)}.`);\n }\n normalizedNames.add(name);\n\n const values =\n configuredValue === true\n ? []\n : (Array.isArray(configuredValue) ? configuredValue : [configuredValue]).map(\n validateDirectiveValue,\n );\n serialized.push(values.length > 0 ? `${name} ${values.join(\" \")}` : name);\n }\n\n if (serialized.length === 0) {\n throw new TypeError(\"security.csp.directives must contain at least one enabled directive.\");\n }\n return serialized.join(\"; \");\n}\n\nexport function getFarmSecurityHeader(\n security: ResolvedFarmSecurityConfig,\n): { key: string; value: string } | undefined {\n if (!security.csp) return undefined;\n return {\n key: security.csp.reportOnly\n ? \"Content-Security-Policy-Report-Only\"\n : \"Content-Security-Policy\",\n value: security.csp.value,\n };\n}\n\nfunction normalizeDirectiveName(value: string): string {\n const name = value\n .trim()\n .replace(/([a-z0-9])([A-Z])/g, \"$1-$2\")\n .toLowerCase();\n if (!/^[a-z][a-z0-9-]*$/.test(name)) {\n throw new TypeError(`Invalid security.csp directive name: ${JSON.stringify(value)}.`);\n }\n return name;\n}\n\nfunction validateDirectiveValue(value: string): string {\n if (typeof value !== \"string\") {\n throw new TypeError(\"security.csp directive values must be strings or booleans.\");\n }\n const normalized = value.trim();\n if (!normalized || /[;\\r\\n]/.test(normalized) || normalized.includes(\"\\0\")) {\n throw new TypeError(`Invalid security.csp directive value: ${JSON.stringify(value)}.`);\n }\n return normalized;\n}\n\nfunction validateSerializedCsp(value: unknown): string {\n if (typeof value !== \"string\") {\n throw new TypeError(\"security.csp policy must be a non-empty single-line string.\");\n }\n const normalized = value.trim().replace(/;+$/g, \"\").trim();\n if (!normalized || /[\\r\\n]/.test(normalized) || normalized.includes(\"\\0\")) {\n throw new TypeError(\"security.csp policy must be a non-empty single-line string.\");\n }\n return normalized;\n}\n\nfunction validateReportOnly(value: unknown): boolean {\n if (value === undefined) return false;\n if (typeof value !== \"boolean\") {\n throw new TypeError(\"security.csp.reportOnly must be a boolean.\");\n }\n return value;\n}\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return false;\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n}\n"],"mappings":"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","names":[]}
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-V7RBCSDJ.mjs";
5
5
  import {
6
6
  resolveDocsConfig
7
- } from "./chunk-T2KL7VEL.mjs";
7
+ } from "./chunk-PZXBQKCH.mjs";
8
8
  import {
9
9
  resolveFarmDocsFontAssets,
10
10
  toFarmDocsPublicFontAssets
@@ -4002,4 +4002,4 @@ export {
4002
4002
  createDocsAPI,
4003
4003
  createFarmDocsAPIHandler
4004
4004
  };
4005
- //# sourceMappingURL=chunk-SLDBGSC3.mjs.map
4005
+ //# sourceMappingURL=chunk-JAEAE27K.mjs.map
@@ -3,9 +3,11 @@ import {
3
3
  setEnv
4
4
  } from "./chunk-RQ633A5I.mjs";
5
5
  import {
6
+ getFarmSecurityHeader,
6
7
  resolveFarmAuthConfig,
7
- resolveFarmAuthIntegration
8
- } from "./chunk-I4CUBGVF.mjs";
8
+ resolveFarmAuthIntegration,
9
+ resolveFarmSecurityConfig
10
+ } from "./chunk-E257KFBU.mjs";
9
11
  import {
10
12
  resolveFarmDevtoolsConfig
11
13
  } from "./chunk-7MABZJIM.mjs";
@@ -336,6 +338,8 @@ async function resolveConfig(userConfig, mode) {
336
338
  const routeRules = normalizeRouteRules(userConfig.routeRules);
337
339
  const routeRuleRedirects = routeRulesToRedirects(routeRules);
338
340
  const routeRuleHeaders = routeRulesToHeaders(routeRules);
341
+ const security = resolveFarmSecurityConfig(userConfig.security);
342
+ const securityHeader = getFarmSecurityHeader(security);
339
343
  const deploy = resolveDeployConfig(userConfig);
340
344
  const root = userConfig.root || process.cwd();
341
345
  const srcDir = userConfig.srcDir || "src";
@@ -391,7 +395,11 @@ async function resolveConfig(userConfig, mode) {
391
395
  trailingSlash: userConfig.trailingSlash ?? false,
392
396
  redirects: /* @__PURE__ */ __name(() => [...redirects, ...routeRuleRedirects], "redirects"),
393
397
  rewrites: /* @__PURE__ */ __name(() => rewrites, "rewrites"),
394
- headers: /* @__PURE__ */ __name(() => [...headers, ...routeRuleHeaders], "headers"),
398
+ headers: /* @__PURE__ */ __name(() => [
399
+ ...headers,
400
+ ...routeRuleHeaders,
401
+ ...securityHeader ? [{ source: "/*", headers: [securityHeader] }] : []
402
+ ], "headers"),
395
403
  routeRules,
396
404
  images: resolveFarmImageConfig(userConfig.images),
397
405
  performance: resolveFarmPerformanceConfig(userConfig.performance),
@@ -410,6 +418,7 @@ async function resolveConfig(userConfig, mode) {
410
418
  notFound: userConfig.notFound || {},
411
419
  context: userConfig.context || (() => void 0),
412
420
  serverActions: resolveServerActionsConfig(userConfig.serverActions),
421
+ security,
413
422
  deploymentId,
414
423
  output: userConfig.output || "standalone",
415
424
  distDir: userConfig.distDir || ".farm",
@@ -484,4 +493,4 @@ export {
484
493
  resolveConfig,
485
494
  loadConfig
486
495
  };
487
- //# sourceMappingURL=chunk-T2KL7VEL.mjs.map
496
+ //# sourceMappingURL=chunk-PZXBQKCH.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/config.ts"],"sourcesContent":["import type {\n FarmConfig as BaseFarmConfig,\n FarmMigrationCommand,\n FarmMigrationsConfig,\n FarmMigrationsUserConfig,\n ResolvedFarmMigrationsConfig,\n} from \"./types\";\nimport type { DocsConfig } from \"@farming-labs/docs\";\nimport type { FarmDocsResolvedConfig, FarmDocsUserConfig } from \"./docs/types\";\nimport type { FarmIntegrationsUserConfig } from \"./integrations\";\nimport type { FarmMarkdownResolvedConfig, FarmMarkdownUserConfig } from \"./markdown\";\nimport type { FarmObservabilityUserConfig } from \"./observability\";\nimport type { FarmMiddlewareConfig } from \"./middleware/types\";\nimport type { FarmPlugin } from \"./plugin\";\nimport type { FarmWorkflowsResolvedConfig, FarmWorkflowsUserConfig } from \"./workflows\";\nimport type { FarmCronResolvedConfig, FarmCronUserConfig } from \"./cron\";\nimport type { FarmEnvConfig, ResolvedFarmEnv } from \"./env\";\nimport type { UserConfig as ViteUserConfig } from \"vite\";\nimport { resolveIntegrationPlugins } from \"./integrations\";\nimport { resolveMarkdownConfig } from \"./markdown\";\nimport { resolveWorkflowsConfig } from \"./workflows\";\nimport { resolveCronConfig } from \"./cron\";\nimport { resolveEnv, setEnv } from \"./env\";\nimport {\n resolveMdxConfig,\n type FarmMdxResolvedConfig,\n type FarmMdxUserConfig,\n} from \"./app-markdown\";\nimport {\n normalizeRouteRules,\n routeRulesToHeaders,\n routeRulesToRedirects,\n type FarmRouteRules,\n} from \"./route-rules\";\nimport {\n resolveServerActionsConfig,\n type FarmServerActionsConfig,\n type ResolvedFarmServerActionsConfig,\n} from \"./server-action-security\";\nimport {\n loadFarmConfigFile,\n resolveFarmLayers,\n type FarmLayerEntry,\n type ResolvedFarmLayer,\n} from \"./layers\";\nimport path from \"path\";\nimport { normalizeFarmDeploymentId } from \"./deployment\";\nimport { resolveFarmDevtoolsConfig, type ResolvedFarmDevtoolsConfig } from \"./devtools-config\";\nimport {\n resolveFarmImageConfig,\n type FarmImageConfig,\n type ResolvedFarmImageConfig,\n} from \"./image-config\";\nimport { resolveFarmI18nConfig } from \"./i18n/config\";\nimport type { FarmI18nUserConfig, ResolvedFarmI18nConfig } from \"./i18n/types\";\nimport type { FarmCacheUserConfig } from \"./cache\";\nimport {\n resolveFarmAuthConfig,\n resolveFarmAuthIntegration,\n type FarmAuthUserConfig,\n type ResolvedFarmAuthConfig,\n} from \"./auth-config\";\nimport { resolveFarmPerformanceConfig, type ResolvedFarmPerformanceConfig } from \"./preload\";\nimport {\n getFarmSecurityHeader,\n resolveFarmSecurityConfig,\n type FarmCspConfig,\n type FarmCspDirectives,\n type FarmCspDirectiveValue,\n type FarmCspOptions,\n type FarmSecurityConfig,\n type ResolvedFarmCspConfig,\n type ResolvedFarmSecurityConfig,\n} from \"./security\";\n\nconst FARM_RESOLVED_CUSTOM_CONTEXT = Symbol.for(\"farm.resolvedCustomContext\");\n\nexport type {\n FarmDocsConfigInput,\n FarmDocsNavigationConfig,\n FarmDocsResolvedConfig,\n FarmDocsSidebarItem,\n FarmDocsUserConfig,\n} from \"./docs/types\";\nexport type {\n FarmMarkdownResolvedConfig,\n FarmMarkdownRouteInput,\n FarmMarkdownUserConfig,\n} from \"./markdown\";\nexport type { FarmMdxComponents, FarmMdxResolvedConfig, FarmMdxUserConfig } from \"./app-markdown\";\nexport type {\n FarmMigrationCommand,\n FarmMigrationsConfig,\n FarmMigrationsUserConfig,\n ResolvedFarmMigrationsConfig,\n} from \"./types\";\nexport type { FarmWorkflowsResolvedConfig, FarmWorkflowsUserConfig } from \"./workflows\";\nexport type { FarmCronJobConfig, FarmCronResolvedConfig, FarmCronUserConfig } from \"./cron\";\nexport type {\n FarmRouteRule,\n FarmRouteRuleCors,\n FarmRouteRuleRedirect,\n FarmRouteRuleRenderMode,\n FarmRouteRules,\n} from \"./route-rules\";\nexport type {\n FarmServerActionsConfig,\n ResolvedFarmServerActionsConfig,\n} from \"./server-action-security\";\nexport type { FarmLayerEntry, ResolvedFarmLayer } from \"./layers\";\nexport type {\n FarmDevtoolsConfig,\n FarmDevtoolsUserConfig,\n ResolvedFarmDevtoolsConfig,\n} from \"./devtools-config\";\nexport type {\n FarmPerformanceConfig,\n FarmPreloadMode,\n FarmPreloadUserConfig,\n ResolvedFarmPerformanceConfig,\n ResolvedFarmPreloadConfig,\n} from \"./preload\";\nexport type {\n FarmImageConfig,\n FarmImageFormat,\n FarmImageLocalPattern,\n FarmImageProvider,\n FarmImageRemotePattern,\n ResolvedFarmImageConfig,\n} from \"./image-config\";\nexport type {\n FarmI18nCookieConfig,\n FarmI18nDetectionSignal,\n FarmI18nDirection,\n FarmI18nRouting,\n FarmI18nUserConfig,\n ResolvedFarmI18nConfig,\n} from \"./i18n/types\";\nexport type {\n FarmAuthConfig,\n FarmAuthDatabaseConfig,\n FarmAuthEmailAndPasswordConfig,\n FarmAuthSessionConfig,\n FarmAuthUserConfig,\n ResolvedFarmAuthConfig,\n} from \"./auth-config\";\nexport type {\n FarmCspConfig,\n FarmCspDirectives,\n FarmCspDirectiveValue,\n FarmCspOptions,\n FarmSecurityConfig,\n ResolvedFarmCspConfig,\n ResolvedFarmSecurityConfig,\n} from \"./security\";\n\nexport interface RedirectConfig {\n source: string;\n destination: string;\n permanent?: boolean;\n statusCode?: number;\n}\n\nexport interface HeaderConfig {\n source: string;\n headers: Array<{\n key: string;\n value: string;\n }>;\n}\n\nexport interface RewriteConfig {\n source: string;\n destination: string;\n}\n\n/** @deprecated Use FarmImageConfig. */\nexport type ImageConfig = FarmImageConfig;\n\n/** @deprecated Use FarmI18nUserConfig. */\nexport type I18nConfig = FarmI18nUserConfig;\n\nexport interface OpenAPIConfig {\n enabled?: boolean;\n route?: string;\n title?: string;\n description?: string;\n version?: string;\n servers?: Array<{\n url: string;\n description?: string;\n }>;\n contact?: {\n name?: string;\n email?: string;\n url?: string;\n };\n license?: {\n name: string;\n url?: string;\n };\n}\n\nexport type MiddlewareConfig = FarmMiddlewareConfig;\n\nexport interface NotFoundConfig {\n /** Path to a custom 404 page component (e.g., \"./src/app/not-found.tsx\") */\n component?: string;\n}\n\nexport type FarmDeployTarget = \"vercel\" | \"cloudflare\" | \"netlify\" | \"node\" | string;\n\nexport interface FarmDeployConfig {\n /**\n * Deployment platform. When present, Farm picks the matching Nitro preset and\n * output directory unless explicitly overridden.\n */\n target?: FarmDeployTarget;\n /** Nitro preset override. Usually inferred from target. */\n preset?: BaseFarmConfig[\"preset\"];\n /** Deployable output directory, relative to project root unless absolute. */\n outputDir?: string;\n /** Alias for outputDir for terser config. */\n output?: string;\n /** Cloudflare Pages project name used by `farm deploy --cloudflare`. */\n projectName?: string;\n vercel?: {\n outputDirectory?: string;\n buildCommand?: string;\n installCommand?: string;\n framework?: string | null;\n };\n cloudflare?: {\n outputDir?: string;\n projectName?: string;\n };\n netlify?: {\n outputDir?: string;\n site?: string;\n };\n}\n\nexport interface ResolvedFarmDeployConfig extends Omit<FarmDeployConfig, \"output\"> {\n target?: FarmDeployTarget;\n preset: BaseFarmConfig[\"preset\"];\n outputDir: string;\n}\n\nexport interface FarmUserConfig extends Omit<BaseFarmConfig, \"vite\" | \"docs\" | \"env\" | \"layers\"> {\n /** Reusable Farm directories or installed packages, applied from left to right. */\n extends?: readonly FarmLayerEntry[];\n plugins?: FarmPlugin[];\n integrations?: FarmIntegrationsUserConfig;\n /**\n * Farm-native authentication. `true` enables email/password auth with\n * server helpers from `@farm.js/auth/server` and React APIs from\n * `@farm.js/auth/client`.\n */\n auth?: FarmAuthUserConfig;\n /** Shared application data, route, ISR, and PPR cache. */\n cache?: FarmCacheUserConfig;\n migrations?: FarmMigrationsUserConfig;\n /** Map portable cron schedules to ordinary GET API routes. */\n cron?: FarmCronUserConfig | FarmCronResolvedConfig | false;\n workflows?: FarmWorkflowsUserConfig | boolean;\n preset?: BaseFarmConfig[\"preset\"];\n deploy?: FarmDeployConfig;\n docs?: FarmDocsUserConfig;\n md?: FarmMarkdownUserConfig | boolean;\n mdx?: FarmMdxUserConfig;\n observability?: FarmObservabilityUserConfig;\n\n trailingSlash?: boolean;\n redirects?: () => Promise<RedirectConfig[]> | RedirectConfig[];\n rewrites?: () => Promise<RewriteConfig[]> | RewriteConfig[];\n headers?: () => Promise<HeaderConfig[]> | HeaderConfig[];\n\n images?: ImageConfig;\n publicDir?: string;\n\n i18n?: FarmI18nUserConfig | false;\n openapi?: OpenAPIConfig;\n\n middleware?: FarmMiddlewareConfig;\n routeRules?: FarmRouteRules;\n context?: BaseFarmConfig[\"context\"];\n serverActions?: FarmServerActionsConfig;\n /** Build identifier used to detect and recover from deployment version skew. */\n deploymentId?: string;\n\n notFound?: NotFoundConfig;\n\n output?: \"standalone\" | \"static\" | \"export\";\n distDir?: string;\n generateBuildId?: () => string | Promise<string>;\n compress?: boolean;\n\n devIndicators?: {\n buildActivity?: boolean;\n buildActivityPosition?: \"bottom-right\" | \"bottom-left\" | \"top-right\" | \"top-left\";\n };\n\n serverRuntimeConfig?: Record<string, any>;\n publicRuntimeConfig?: Record<string, any>;\n\n env?: FarmEnvConfig<any, any>;\n\n typescript?: {\n tsconfigPath?: string;\n ignoreBuildErrors?: boolean;\n };\n\n vite?: ViteUserConfig | ((config: ViteUserConfig) => ViteUserConfig);\n\n [key: string]: any;\n}\n\nexport interface ResolvedFarmConfig extends Required<\n Omit<\n FarmUserConfig,\n | \"extends\"\n | \"plugins\"\n | \"vite\"\n | \"deploy\"\n | \"docs\"\n | \"md\"\n | \"mdx\"\n | \"migrations\"\n | \"cron\"\n | \"workflows\"\n | \"env\"\n | \"serverActions\"\n | \"devtools\"\n | \"images\"\n | \"i18n\"\n | \"auth\"\n | \"performance\"\n | \"security\"\n >\n> {\n /** @internal Tracks whether `context` came from user/layer config instead of the default noop. */\n [FARM_RESOLVED_CUSTOM_CONTEXT]?: boolean;\n extends: readonly FarmLayerEntry[];\n layers: ResolvedFarmLayer[];\n plugins: FarmPlugin[];\n vite: ViteUserConfig;\n deploy: ResolvedFarmDeployConfig;\n docs: FarmDocsResolvedConfig;\n md: FarmMarkdownResolvedConfig;\n mdx: FarmMdxResolvedConfig;\n migrations: ResolvedFarmMigrationsConfig;\n cron: FarmCronResolvedConfig;\n workflows: FarmWorkflowsResolvedConfig;\n env: ResolvedFarmEnv;\n serverActions: ResolvedFarmServerActionsConfig;\n devtools: ResolvedFarmDevtoolsConfig;\n images: ResolvedFarmImageConfig;\n i18n: ResolvedFarmI18nConfig;\n auth: ResolvedFarmAuthConfig;\n performance: ResolvedFarmPerformanceConfig;\n security: ResolvedFarmSecurityConfig;\n routeRules: FarmRouteRules;\n}\n\nexport function hasCustomFarmRouteContext(config: ResolvedFarmConfig): boolean {\n return config[FARM_RESOLVED_CUSTOM_CONTEXT] === true;\n}\n\nexport type FarmLayerConfig = Omit<\n FarmUserConfig,\n | \"root\"\n | \"outDir\"\n | \"distDir\"\n | \"deploy\"\n | \"output\"\n | \"preset\"\n | \"publicDir\"\n | \"generateBuildId\"\n | \"deploymentId\"\n>;\n\nexport { defineConfig, defineFarmConfig } from \"./config-entry\";\n\nexport function normalizeDeployTarget(target?: FarmDeployTarget): FarmDeployTarget | undefined {\n if (!target) return undefined;\n if (target === \"cloudflare-pages\" || target === \"cloudflare_pages\") return \"cloudflare\";\n if (target === \"node-server\" || target === \"nitro\") return \"node\";\n return target;\n}\n\nexport function getPresetForDeployTarget(\n target?: FarmDeployTarget,\n): BaseFarmConfig[\"preset\"] | undefined {\n switch (normalizeDeployTarget(target)) {\n case \"vercel\":\n return \"vercel\";\n case \"cloudflare\":\n return \"cloudflare-pages\";\n case \"netlify\":\n return \"netlify\";\n case \"node\":\n return \"node-server\";\n default:\n return undefined;\n }\n}\n\nexport function getDeployTargetForPreset(preset?: string): FarmDeployTarget | undefined {\n if (!preset) return undefined;\n if (preset === \"vercel\" || preset === \"vercel-edge\") return \"vercel\";\n if (preset === \"cloudflare\" || preset === \"cloudflare-pages\" || preset === \"cloudflare-module\") {\n return \"cloudflare\";\n }\n if (preset === \"netlify\" || preset === \"netlify-edge\") return \"netlify\";\n if (preset === \"node-server\") return \"node\";\n return undefined;\n}\n\nexport function getDefaultDeployOutputDir(\n target: FarmDeployTarget | undefined,\n preset: string | undefined,\n distDir: string,\n): string {\n const normalizedTarget = normalizeDeployTarget(target) || getDeployTargetForPreset(preset);\n if (normalizedTarget === \"vercel\") return \".vercel/output\";\n return `${distDir}/.output`;\n}\n\nexport function resolveDeployOutputPath(root: string, outputDir: string): string {\n return path.isAbsolute(outputDir) ? outputDir : path.join(root, outputDir);\n}\n\nexport function resolveDeployConfig(\n config: Pick<FarmUserConfig, \"deploy\" | \"preset\" | \"distDir\">,\n overrides: {\n target?: FarmDeployTarget;\n preset?: BaseFarmConfig[\"preset\"];\n outputDir?: string;\n } = {},\n): ResolvedFarmDeployConfig {\n const deploy = config.deploy || {};\n const distDir = config.distDir || \".farm\";\n const target = normalizeDeployTarget(overrides.target || deploy.target);\n const preset =\n overrides.preset ||\n deploy.preset ||\n config.preset ||\n getPresetForDeployTarget(target) ||\n \"node-server\";\n const resolvedTarget = target || getDeployTargetForPreset(preset);\n const platformOutput =\n resolvedTarget === \"vercel\"\n ? deploy.vercel?.outputDirectory\n : resolvedTarget === \"cloudflare\"\n ? deploy.cloudflare?.outputDir\n : resolvedTarget === \"netlify\"\n ? deploy.netlify?.outputDir\n : undefined;\n const outputDir =\n overrides.outputDir ||\n deploy.outputDir ||\n deploy.output ||\n platformOutput ||\n getDefaultDeployOutputDir(resolvedTarget, preset, distDir);\n\n return {\n ...deploy,\n target: resolvedTarget,\n preset,\n outputDir,\n };\n}\n\nexport function resolveMigrationsConfig(\n migrations: FarmMigrationsUserConfig | undefined,\n): ResolvedFarmMigrationsConfig {\n if (!migrations) return { commands: [] };\n if (Array.isArray(migrations)) return { commands: migrations };\n return { commands: migrations.commands || [] };\n}\n\nexport const DOCS_CONFIG_FILENAMES = [\n \"docs.config.ts\",\n \"docs.config.tsx\",\n \"docs.config.mts\",\n \"docs.config.cts\",\n \"docs.config.js\",\n \"docs.config.jsx\",\n \"docs.config.mjs\",\n \"docs.config.cjs\",\n \"docs.json\",\n];\n\nfunction normalizeDocsRoute(value: string | undefined, fallback = \"/docs\"): string {\n const raw = (value || fallback).trim();\n if (!raw || raw === \"/\") return \"/\";\n const normalized = raw\n .replace(/\\\\/g, \"/\")\n .replace(/\\/+/g, \"/\")\n .replace(/^\\/?/, \"/\")\n .replace(/\\/+$/, \"\");\n return normalized || \"/\";\n}\n\nfunction docsRouteToEntry(route: string): string {\n const entry = route.replace(/^\\/+/, \"\").replace(/\\/+$/, \"\");\n return entry || \"docs\";\n}\n\nfunction normalizeDocsContentDir(value: string | undefined): string | undefined {\n if (!value) return undefined;\n const normalized = value.replace(/\\\\/g, \"/\").replace(/^\\/+/, \"\").replace(/\\/+$/, \"\");\n return normalized || undefined;\n}\n\nfunction isRecord(value: unknown): value is Record<string, any> {\n return !!value && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction cloneSerializable(value: unknown, seen = new WeakSet<object>()): any {\n if (value === null) return null;\n\n const valueType = typeof value;\n if (valueType === \"string\" || valueType === \"number\" || valueType === \"boolean\") {\n return value;\n }\n if (valueType === \"undefined\" || valueType === \"function\" || valueType === \"symbol\") {\n return undefined;\n }\n if (Array.isArray(value)) {\n return value.map((item) => cloneSerializable(item, seen)).filter((item) => item !== undefined);\n }\n if (value instanceof Date) {\n return value.toISOString();\n }\n if (isRecord(value)) {\n if (seen.has(value)) return undefined;\n seen.add(value);\n\n const output: Record<string, any> = {};\n for (const [key, nestedValue] of Object.entries(value)) {\n const clonedValue = cloneSerializable(nestedValue, seen);\n if (clonedValue !== undefined) {\n output[key] = clonedValue;\n }\n }\n return output;\n }\n\n return undefined;\n}\n\nfunction sanitizeDocsConfig(config: Partial<DocsConfig>): Partial<DocsConfig> {\n return cloneSerializable(config) || {};\n}\n\nexport async function findDocsConfigPath(\n rootDir: string,\n configPath?: string,\n): Promise<string | undefined> {\n const { existsSync } = await import(\"fs\");\n const root = path.resolve(rootDir || process.cwd());\n\n if (configPath) {\n const resolvedPath = path.isAbsolute(configPath) ? configPath : path.join(root, configPath);\n if (!existsSync(resolvedPath)) {\n throw new Error(`Could not find docs config at ${configPath}.`);\n }\n return path.resolve(resolvedPath);\n }\n\n for (const filename of DOCS_CONFIG_FILENAMES) {\n const resolvedPath = path.join(root, filename);\n if (existsSync(resolvedPath)) {\n return resolvedPath;\n }\n }\n\n return undefined;\n}\n\nexport async function loadDocsConfig(\n rootDir: string,\n configPath?: string,\n): Promise<{ config: Partial<DocsConfig>; configPath: string } | undefined> {\n const fs = await import(\"fs/promises\");\n const { pathToFileURL } = await import(\"url\");\n const root = path.resolve(rootDir || process.cwd());\n const resolvedPath = await findDocsConfigPath(root, configPath);\n\n if (!resolvedPath) return undefined;\n\n try {\n if (resolvedPath.endsWith(\".json\")) {\n const content = await fs.readFile(resolvedPath, \"utf8\");\n return { config: JSON.parse(content), configPath: resolvedPath };\n }\n\n const { build } = await import(\"esbuild\");\n const configCacheDir = path.join(root, \".farm\", \".config-loader\");\n await fs.mkdir(configCacheDir, { recursive: true });\n const modulePath = path.join(\n configCacheDir,\n `docs-config-${Date.now()}-${Math.random().toString(36).slice(2)}.mjs`,\n );\n\n await build({\n absWorkingDir: root,\n entryPoints: [resolvedPath],\n outfile: modulePath,\n bundle: true,\n format: \"esm\",\n platform: \"node\",\n target: `node${process.versions.node.split(\".\")[0]}`,\n packages: \"external\",\n jsx: \"automatic\",\n logLevel: \"silent\",\n sourcemap: \"inline\",\n });\n\n const moduleUrl = pathToFileURL(modulePath).href + `?t=${Date.now()}`;\n let importedConfig: any;\n\n try {\n importedConfig = await import(/* @vite-ignore */ moduleUrl);\n } finally {\n await fs.unlink(modulePath).catch(() => undefined);\n }\n\n return {\n config: importedConfig.default || importedConfig,\n configPath: resolvedPath,\n };\n } catch (error: any) {\n const relativePath = path.relative(root, resolvedPath) || resolvedPath;\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to load docs config from ${relativePath}: ${message}`);\n }\n}\n\nexport async function resolveDocsConfig(\n userDocs: FarmDocsUserConfig | undefined,\n options: {\n root?: string;\n srcDir?: string;\n } = {},\n): Promise<FarmDocsResolvedConfig> {\n const root = options.root || process.cwd();\n\n if (userDocs === false) {\n return {\n enabled: false,\n entry: \"/docs\",\n config: { entry: \"docs\", docsPath: \"/docs\" },\n };\n }\n\n const docsOptions = isRecord(userDocs) ? userDocs : {};\n if (docsOptions.enabled === false) {\n return {\n enabled: false,\n entry: \"/docs\",\n config: { entry: \"docs\", docsPath: \"/docs\" },\n };\n }\n\n const loadedConfig = await loadDocsConfig(root, docsOptions.configPath);\n const hasExplicitDocsConfig = userDocs === true || isRecord(userDocs);\n\n if (!hasExplicitDocsConfig && !loadedConfig) {\n return {\n enabled: false,\n entry: \"/docs\",\n config: { entry: \"docs\", docsPath: \"/docs\" },\n };\n }\n\n const inlineDocsConfig = sanitizeDocsConfig(docsOptions.config || {});\n const directDocsConfig = sanitizeDocsConfig({\n ...docsOptions,\n enabled: undefined,\n config: undefined,\n configPath: undefined,\n } as Partial<DocsConfig>);\n const loadedDocsConfig = sanitizeDocsConfig(loadedConfig?.config || {});\n const mergedDocsConfig: Partial<DocsConfig> = {\n ...loadedDocsConfig,\n ...inlineDocsConfig,\n ...directDocsConfig,\n };\n\n const explicitRoute = typeof docsOptions.entry === \"string\" ? docsOptions.entry : undefined;\n const configuredDocsPath =\n typeof mergedDocsConfig.docsPath === \"string\" ? mergedDocsConfig.docsPath : undefined;\n const configuredEntry =\n typeof mergedDocsConfig.entry === \"string\" ? mergedDocsConfig.entry : undefined;\n const entryRoute = normalizeDocsRoute(\n configuredDocsPath || explicitRoute || (configuredEntry ? `/${configuredEntry}` : undefined),\n );\n const docsEntry =\n explicitRoute && explicitRoute.startsWith(\"/\")\n ? docsRouteToEntry(explicitRoute)\n : docsRouteToEntry(configuredEntry || entryRoute);\n const contentDir = normalizeDocsContentDir(docsOptions.contentDir || mergedDocsConfig.contentDir);\n\n return {\n enabled: true,\n entry: entryRoute,\n contentDir,\n configPath: loadedConfig?.configPath,\n config: {\n ...mergedDocsConfig,\n entry: docsEntry,\n docsPath: entryRoute,\n ...(contentDir ? { contentDir } : {}),\n },\n };\n}\n\nexport async function resolveConfig(\n userConfig: FarmUserConfig,\n mode: \"development\" | \"production\",\n): Promise<ResolvedFarmConfig> {\n const projectRoot = userConfig.root || process.cwd();\n const layerResolution = await resolveFarmLayers(userConfig, {\n root: projectRoot,\n mode,\n });\n userConfig = layerResolution.config;\n\n const redirects =\n typeof userConfig.redirects === \"function\"\n ? await userConfig.redirects()\n : userConfig.redirects || [];\n\n const rewrites =\n typeof userConfig.rewrites === \"function\"\n ? await userConfig.rewrites()\n : userConfig.rewrites || [];\n\n const headers =\n typeof userConfig.headers === \"function\"\n ? await userConfig.headers()\n : userConfig.headers || [];\n const routeRules = normalizeRouteRules(userConfig.routeRules);\n const routeRuleRedirects = routeRulesToRedirects(routeRules);\n const routeRuleHeaders = routeRulesToHeaders(routeRules);\n const security = resolveFarmSecurityConfig(userConfig.security);\n const securityHeader = getFarmSecurityHeader(security);\n\n const deploy = resolveDeployConfig(userConfig);\n const root = userConfig.root || process.cwd();\n const srcDir = userConfig.srcDir || \"src\";\n const docs = await resolveDocsConfig(userConfig.docs, { root, srcDir });\n const md = resolveMarkdownConfig(userConfig.md);\n const mdx = resolveMdxConfig(userConfig.mdx);\n const env = resolveEnv(userConfig.env, process.env);\n setEnv(env);\n const auth = resolveFarmAuthConfig(userConfig.auth);\n if (auth.enabled && userConfig.integrations?.auth) {\n throw new Error(\n \"Choose either the top-level `auth` config or `integrations.auth`; they cannot both own the auth route.\",\n );\n }\n const nativeAuthIntegration = await resolveFarmAuthIntegration(auth, {\n root,\n mode,\n });\n const integrations = nativeAuthIntegration\n ? { ...userConfig.integrations, auth: nativeAuthIntegration }\n : userConfig.integrations || {};\n const generateBuildId = userConfig.generateBuildId || (() => `build-${Date.now()}`);\n const deploymentId = normalizeFarmDeploymentId(\n userConfig.deploymentId ||\n process.env.FARM_DEPLOYMENT_ID ||\n process.env.VERCEL_GIT_COMMIT_SHA ||\n process.env.CF_PAGES_COMMIT_SHA ||\n (mode === \"production\" ? await generateBuildId() : \"development\"),\n );\n\n const resolved: ResolvedFarmConfig = {\n [FARM_RESOLVED_CUSTOM_CONTEXT]: typeof userConfig.context === \"function\",\n root,\n srcDir,\n extends: userConfig.extends || [],\n layers: layerResolution.layers,\n outDir: userConfig.outDir || \"dist\",\n basePath: userConfig.basePath || \"/\",\n preset: deploy.preset || \"node-server\",\n deploy,\n docs,\n md,\n mdx,\n migrations: resolveMigrationsConfig(userConfig.migrations),\n cron: resolveCronConfig(userConfig.cron),\n workflows: resolveWorkflowsConfig(userConfig.workflows),\n observability: userConfig.observability ?? false,\n devtools: resolveFarmDevtoolsConfig(userConfig.devtools, mode),\n storage: userConfig.storage || {},\n cache: userConfig.cache || {},\n auth,\n suppressLintOnLink: userConfig.suppressLintOnLink ?? false,\n experimental: {\n serverComponents: false,\n serverActions: false,\n ...userConfig.experimental,\n },\n plugins: [...resolveIntegrationPlugins(integrations), ...(userConfig.plugins || [])],\n integrations,\n trailingSlash: userConfig.trailingSlash ?? false,\n redirects: () => [...redirects, ...routeRuleRedirects],\n rewrites: () => rewrites,\n headers: () => [\n ...headers,\n ...routeRuleHeaders,\n ...(securityHeader ? [{ source: \"/*\", headers: [securityHeader] }] : []),\n ],\n routeRules,\n images: resolveFarmImageConfig(userConfig.images),\n performance: resolveFarmPerformanceConfig(userConfig.performance),\n publicDir: userConfig.publicDir || \"public\",\n i18n: resolveFarmI18nConfig(userConfig.i18n, { root, mode }),\n openapi: {\n enabled: false,\n route: \"/docs/reference\",\n title: \"API Documentation\",\n description: \"Auto-generated API documentation\",\n version: \"1.0.0\",\n servers: [{ url: \"http://localhost:3000\", description: \"Development server\" }],\n ...userConfig.openapi,\n },\n middleware: userConfig.middleware || {},\n notFound: userConfig.notFound || {},\n context: userConfig.context || (() => undefined),\n serverActions: resolveServerActionsConfig(userConfig.serverActions),\n security,\n deploymentId,\n output: userConfig.output || \"standalone\",\n distDir: userConfig.distDir || \".farm\",\n generateBuildId,\n compress: userConfig.compress ?? true,\n devIndicators: {\n buildActivity: true,\n buildActivityPosition: \"bottom-right\",\n ...userConfig.devIndicators,\n },\n serverRuntimeConfig: userConfig.serverRuntimeConfig || {},\n publicRuntimeConfig: userConfig.publicRuntimeConfig || {},\n env,\n typescript: {\n tsconfigPath: \"tsconfig.json\",\n ignoreBuildErrors: false,\n ...userConfig.typescript,\n },\n vite: typeof userConfig.vite === \"function\" ? userConfig.vite({}) : userConfig.vite || {},\n };\n\n return resolved;\n}\n\nexport async function loadConfig(\n rootDir?: string,\n configPath?: string,\n mode = process.env.NODE_ENV === \"production\" ? \"production\" : \"development\",\n loadEnvironment?: (typeof import(\"vite\"))[\"loadEnv\"],\n): Promise<FarmUserConfig | undefined> {\n const { existsSync } = await import(\"fs\");\n const loadEnv = loadEnvironment || (await import(\"vite\")).loadEnv;\n\n const root = rootDir || process.cwd();\n const loadedEnv = loadEnv(mode, root, \"\");\n for (const [key, value] of Object.entries(loadedEnv)) {\n if (process.env[key] === undefined) {\n process.env[key] = value;\n }\n }\n const searchPaths = [\n configPath,\n \"farm.config.ts\",\n \"farm.config.mts\",\n \"farm.config.js\",\n \"farm.config.mjs\",\n \"config.ts\",\n \"config.mts\",\n \"config.js\",\n \"config.mjs\",\n ].filter(Boolean) as string[];\n\n for (const relativePath of searchPaths) {\n try {\n // Use path.join for proper path construction\n const absolutePath = relativePath.startsWith(\"/\")\n ? relativePath\n : path.join(root, relativePath);\n\n // Normalize the path to handle any issues\n const normalizedPath = path.resolve(absolutePath);\n\n // Check if file exists before trying to import\n if (!existsSync(normalizedPath)) {\n continue;\n }\n\n const loadedConfig = await loadFarmConfigFile<FarmUserConfig>(normalizedPath, { root });\n return loadedConfig.root === undefined ? { ...loadedConfig, root } : loadedConfig;\n } catch (error: any) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to load config from ${relativePath}: ${message}`);\n }\n }\n return undefined;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6CA,OAAO,UAAU;AA8BjB,IAAM,+BAA+B,uBAAO,IAAI,4BAA4B;AAiSrE,SAAS,0BAA0B,QAAqC;AAC7E,SAAO,OAAO,4BAA4B,MAAM;AAClD;AAFgB;AAmBT,SAAS,sBAAsB,QAAyD;AAC7F,MAAI,CAAC,OAAQ,QAAO;AACpB,MAAI,WAAW,sBAAsB,WAAW,mBAAoB,QAAO;AAC3E,MAAI,WAAW,iBAAiB,WAAW,QAAS,QAAO;AAC3D,SAAO;AACT;AALgB;AAOT,SAAS,yBACd,QACsC;AACtC,UAAQ,sBAAsB,MAAM,GAAG;AAAA,IACrC,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AAfgB;AAiBT,SAAS,yBAAyB,QAA+C;AACtF,MAAI,CAAC,OAAQ,QAAO;AACpB,MAAI,WAAW,YAAY,WAAW,cAAe,QAAO;AAC5D,MAAI,WAAW,gBAAgB,WAAW,sBAAsB,WAAW,qBAAqB;AAC9F,WAAO;AAAA,EACT;AACA,MAAI,WAAW,aAAa,WAAW,eAAgB,QAAO;AAC9D,MAAI,WAAW,cAAe,QAAO;AACrC,SAAO;AACT;AATgB;AAWT,SAAS,0BACd,QACA,QACA,SACQ;AACR,QAAM,mBAAmB,sBAAsB,MAAM,KAAK,yBAAyB,MAAM;AACzF,MAAI,qBAAqB,SAAU,QAAO;AAC1C,SAAO,GAAG,OAAO;AACnB;AARgB;AAUT,SAAS,wBAAwB,MAAc,WAA2B;AAC/E,SAAO,KAAK,WAAW,SAAS,IAAI,YAAY,KAAK,KAAK,MAAM,SAAS;AAC3E;AAFgB;AAIT,SAAS,oBACd,QACA,YAII,CAAC,GACqB;AAC1B,QAAM,SAAS,OAAO,UAAU,CAAC;AACjC,QAAM,UAAU,OAAO,WAAW;AAClC,QAAM,SAAS,sBAAsB,UAAU,UAAU,OAAO,MAAM;AACtE,QAAM,SACJ,UAAU,UACV,OAAO,UACP,OAAO,UACP,yBAAyB,MAAM,KAC/B;AACF,QAAM,iBAAiB,UAAU,yBAAyB,MAAM;AAChE,QAAM,iBACJ,mBAAmB,WACf,OAAO,QAAQ,kBACf,mBAAmB,eACjB,OAAO,YAAY,YACnB,mBAAmB,YACjB,OAAO,SAAS,YAChB;AACV,QAAM,YACJ,UAAU,aACV,OAAO,aACP,OAAO,UACP,kBACA,0BAA0B,gBAAgB,QAAQ,OAAO;AAE3D,SAAO;AAAA,IACL,GAAG;AAAA,IACH,QAAQ;AAAA,IACR;AAAA,IACA;AAAA,EACF;AACF;AAvCgB;AAyCT,SAAS,wBACd,YAC8B;AAC9B,MAAI,CAAC,WAAY,QAAO,EAAE,UAAU,CAAC,EAAE;AACvC,MAAI,MAAM,QAAQ,UAAU,EAAG,QAAO,EAAE,UAAU,WAAW;AAC7D,SAAO,EAAE,UAAU,WAAW,YAAY,CAAC,EAAE;AAC/C;AANgB;AAQT,IAAM,wBAAwB;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,SAAS,mBAAmB,OAA2B,WAAW,SAAiB;AACjF,QAAM,OAAO,SAAS,UAAU,KAAK;AACrC,MAAI,CAAC,OAAO,QAAQ,IAAK,QAAO;AAChC,QAAM,aAAa,IAChB,QAAQ,OAAO,GAAG,EAClB,QAAQ,QAAQ,GAAG,EACnB,QAAQ,QAAQ,GAAG,EACnB,QAAQ,QAAQ,EAAE;AACrB,SAAO,cAAc;AACvB;AATS;AAWT,SAAS,iBAAiB,OAAuB;AAC/C,QAAM,QAAQ,MAAM,QAAQ,QAAQ,EAAE,EAAE,QAAQ,QAAQ,EAAE;AAC1D,SAAO,SAAS;AAClB;AAHS;AAKT,SAAS,wBAAwB,OAA+C;AAC9E,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,aAAa,MAAM,QAAQ,OAAO,GAAG,EAAE,QAAQ,QAAQ,EAAE,EAAE,QAAQ,QAAQ,EAAE;AACnF,SAAO,cAAc;AACvB;AAJS;AAMT,SAAS,SAAS,OAA8C;AAC9D,SAAO,CAAC,CAAC,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK;AACrE;AAFS;AAIT,SAAS,kBAAkB,OAAgB,OAAO,oBAAI,QAAgB,GAAQ;AAC5E,MAAI,UAAU,KAAM,QAAO;AAE3B,QAAM,YAAY,OAAO;AACzB,MAAI,cAAc,YAAY,cAAc,YAAY,cAAc,WAAW;AAC/E,WAAO;AAAA,EACT;AACA,MAAI,cAAc,eAAe,cAAc,cAAc,cAAc,UAAU;AACnF,WAAO;AAAA,EACT;AACA,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,MAAM,IAAI,CAAC,SAAS,kBAAkB,MAAM,IAAI,CAAC,EAAE,OAAO,CAAC,SAAS,SAAS,MAAS;AAAA,EAC/F;AACA,MAAI,iBAAiB,MAAM;AACzB,WAAO,MAAM,YAAY;AAAA,EAC3B;AACA,MAAI,SAAS,KAAK,GAAG;AACnB,QAAI,KAAK,IAAI,KAAK,EAAG,QAAO;AAC5B,SAAK,IAAI,KAAK;AAEd,UAAM,SAA8B,CAAC;AACrC,eAAW,CAAC,KAAK,WAAW,KAAK,OAAO,QAAQ,KAAK,GAAG;AACtD,YAAM,cAAc,kBAAkB,aAAa,IAAI;AACvD,UAAI,gBAAgB,QAAW;AAC7B,eAAO,GAAG,IAAI;AAAA,MAChB;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AA/BS;AAiCT,SAAS,mBAAmB,QAAkD;AAC5E,SAAO,kBAAkB,MAAM,KAAK,CAAC;AACvC;AAFS;AAIT,eAAsB,mBACpB,SACA,YAC6B;AAC7B,QAAM,EAAE,WAAW,IAAI,MAAM,OAAO,IAAI;AACxC,QAAM,OAAO,KAAK,QAAQ,WAAW,QAAQ,IAAI,CAAC;AAElD,MAAI,YAAY;AACd,UAAM,eAAe,KAAK,WAAW,UAAU,IAAI,aAAa,KAAK,KAAK,MAAM,UAAU;AAC1F,QAAI,CAAC,WAAW,YAAY,GAAG;AAC7B,YAAM,IAAI,MAAM,iCAAiC,UAAU,GAAG;AAAA,IAChE;AACA,WAAO,KAAK,QAAQ,YAAY;AAAA,EAClC;AAEA,aAAW,YAAY,uBAAuB;AAC5C,UAAM,eAAe,KAAK,KAAK,MAAM,QAAQ;AAC7C,QAAI,WAAW,YAAY,GAAG;AAC5B,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAvBsB;AAyBtB,eAAsB,eACpB,SACA,YAC0E;AAC1E,QAAM,KAAK,MAAM,OAAO,aAAa;AACrC,QAAM,EAAE,cAAc,IAAI,MAAM,OAAO,KAAK;AAC5C,QAAM,OAAO,KAAK,QAAQ,WAAW,QAAQ,IAAI,CAAC;AAClD,QAAM,eAAe,MAAM,mBAAmB,MAAM,UAAU;AAE9D,MAAI,CAAC,aAAc,QAAO;AAE1B,MAAI;AACF,QAAI,aAAa,SAAS,OAAO,GAAG;AAClC,YAAM,UAAU,MAAM,GAAG,SAAS,cAAc,MAAM;AACtD,aAAO,EAAE,QAAQ,KAAK,MAAM,OAAO,GAAG,YAAY,aAAa;AAAA,IACjE;AAEA,UAAM,EAAE,MAAM,IAAI,MAAM,OAAO,SAAS;AACxC,UAAM,iBAAiB,KAAK,KAAK,MAAM,SAAS,gBAAgB;AAChE,UAAM,GAAG,MAAM,gBAAgB,EAAE,WAAW,KAAK,CAAC;AAClD,UAAM,aAAa,KAAK;AAAA,MACtB;AAAA,MACA,eAAe,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC,CAAC;AAAA,IAClE;AAEA,UAAM,MAAM;AAAA,MACV,eAAe;AAAA,MACf,aAAa,CAAC,YAAY;AAAA,MAC1B,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,QAAQ,OAAO,QAAQ,SAAS,KAAK,MAAM,GAAG,EAAE,CAAC,CAAC;AAAA,MAClD,UAAU;AAAA,MACV,KAAK;AAAA,MACL,UAAU;AAAA,MACV,WAAW;AAAA,IACb,CAAC;AAED,UAAM,YAAY,cAAc,UAAU,EAAE,OAAO,MAAM,KAAK,IAAI,CAAC;AACnE,QAAI;AAEJ,QAAI;AACF,uBAAiB,MAAM;AAAA;AAAA,QAA0B;AAAA;AAAA,IACnD,UAAE;AACA,YAAM,GAAG,OAAO,UAAU,EAAE,MAAM,MAAM,MAAS;AAAA,IACnD;AAEA,WAAO;AAAA,MACL,QAAQ,eAAe,WAAW;AAAA,MAClC,YAAY;AAAA,IACd;AAAA,EACF,SAAS,OAAY;AACnB,UAAM,eAAe,KAAK,SAAS,MAAM,YAAY,KAAK;AAC1D,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,UAAM,IAAI,MAAM,mCAAmC,YAAY,KAAK,OAAO,EAAE;AAAA,EAC/E;AACF;AAzDsB;AA2DtB,eAAsB,kBACpB,UACA,UAGI,CAAC,GAC4B;AACjC,QAAM,OAAO,QAAQ,QAAQ,QAAQ,IAAI;AAEzC,MAAI,aAAa,OAAO;AACtB,WAAO;AAAA,MACL,SAAS;AAAA,MACT,OAAO;AAAA,MACP,QAAQ,EAAE,OAAO,QAAQ,UAAU,QAAQ;AAAA,IAC7C;AAAA,EACF;AAEA,QAAM,cAAc,SAAS,QAAQ,IAAI,WAAW,CAAC;AACrD,MAAI,YAAY,YAAY,OAAO;AACjC,WAAO;AAAA,MACL,SAAS;AAAA,MACT,OAAO;AAAA,MACP,QAAQ,EAAE,OAAO,QAAQ,UAAU,QAAQ;AAAA,IAC7C;AAAA,EACF;AAEA,QAAM,eAAe,MAAM,eAAe,MAAM,YAAY,UAAU;AACtE,QAAM,wBAAwB,aAAa,QAAQ,SAAS,QAAQ;AAEpE,MAAI,CAAC,yBAAyB,CAAC,cAAc;AAC3C,WAAO;AAAA,MACL,SAAS;AAAA,MACT,OAAO;AAAA,MACP,QAAQ,EAAE,OAAO,QAAQ,UAAU,QAAQ;AAAA,IAC7C;AAAA,EACF;AAEA,QAAM,mBAAmB,mBAAmB,YAAY,UAAU,CAAC,CAAC;AACpE,QAAM,mBAAmB,mBAAmB;AAAA,IAC1C,GAAG;AAAA,IACH,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,YAAY;AAAA,EACd,CAAwB;AACxB,QAAM,mBAAmB,mBAAmB,cAAc,UAAU,CAAC,CAAC;AACtE,QAAM,mBAAwC;AAAA,IAC5C,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,EACL;AAEA,QAAM,gBAAgB,OAAO,YAAY,UAAU,WAAW,YAAY,QAAQ;AAClF,QAAM,qBACJ,OAAO,iBAAiB,aAAa,WAAW,iBAAiB,WAAW;AAC9E,QAAM,kBACJ,OAAO,iBAAiB,UAAU,WAAW,iBAAiB,QAAQ;AACxE,QAAM,aAAa;AAAA,IACjB,sBAAsB,kBAAkB,kBAAkB,IAAI,eAAe,KAAK;AAAA,EACpF;AACA,QAAM,YACJ,iBAAiB,cAAc,WAAW,GAAG,IACzC,iBAAiB,aAAa,IAC9B,iBAAiB,mBAAmB,UAAU;AACpD,QAAM,aAAa,wBAAwB,YAAY,cAAc,iBAAiB,UAAU;AAEhG,SAAO;AAAA,IACL,SAAS;AAAA,IACT,OAAO;AAAA,IACP;AAAA,IACA,YAAY,cAAc;AAAA,IAC1B,QAAQ;AAAA,MACN,GAAG;AAAA,MACH,OAAO;AAAA,MACP,UAAU;AAAA,MACV,GAAI,aAAa,EAAE,WAAW,IAAI,CAAC;AAAA,IACrC;AAAA,EACF;AACF;AA7EsB;AA+EtB,eAAsB,cACpB,YACA,MAC6B;AAC7B,QAAM,cAAc,WAAW,QAAQ,QAAQ,IAAI;AACnD,QAAM,kBAAkB,MAAM,kBAAkB,YAAY;AAAA,IAC1D,MAAM;AAAA,IACN;AAAA,EACF,CAAC;AACD,eAAa,gBAAgB;AAE7B,QAAM,YACJ,OAAO,WAAW,cAAc,aAC5B,MAAM,WAAW,UAAU,IAC3B,WAAW,aAAa,CAAC;AAE/B,QAAM,WACJ,OAAO,WAAW,aAAa,aAC3B,MAAM,WAAW,SAAS,IAC1B,WAAW,YAAY,CAAC;AAE9B,QAAM,UACJ,OAAO,WAAW,YAAY,aAC1B,MAAM,WAAW,QAAQ,IACzB,WAAW,WAAW,CAAC;AAC7B,QAAM,aAAa,oBAAoB,WAAW,UAAU;AAC5D,QAAM,qBAAqB,sBAAsB,UAAU;AAC3D,QAAM,mBAAmB,oBAAoB,UAAU;AACvD,QAAM,WAAW,0BAA0B,WAAW,QAAQ;AAC9D,QAAM,iBAAiB,sBAAsB,QAAQ;AAErD,QAAM,SAAS,oBAAoB,UAAU;AAC7C,QAAM,OAAO,WAAW,QAAQ,QAAQ,IAAI;AAC5C,QAAM,SAAS,WAAW,UAAU;AACpC,QAAM,OAAO,MAAM,kBAAkB,WAAW,MAAM,EAAE,MAAM,OAAO,CAAC;AACtE,QAAM,KAAK,sBAAsB,WAAW,EAAE;AAC9C,QAAM,MAAM,iBAAiB,WAAW,GAAG;AAC3C,QAAM,MAAM,WAAW,WAAW,KAAK,QAAQ,GAAG;AAClD,SAAO,GAAG;AACV,QAAM,OAAO,sBAAsB,WAAW,IAAI;AAClD,MAAI,KAAK,WAAW,WAAW,cAAc,MAAM;AACjD,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,QAAM,wBAAwB,MAAM,2BAA2B,MAAM;AAAA,IACnE;AAAA,IACA;AAAA,EACF,CAAC;AACD,QAAM,eAAe,wBACjB,EAAE,GAAG,WAAW,cAAc,MAAM,sBAAsB,IAC1D,WAAW,gBAAgB,CAAC;AAChC,QAAM,kBAAkB,WAAW,oBAAoB,MAAM,SAAS,KAAK,IAAI,CAAC;AAChF,QAAM,eAAe;AAAA,IACnB,WAAW,gBACT,QAAQ,IAAI,sBACZ,QAAQ,IAAI,yBACZ,QAAQ,IAAI,wBACX,SAAS,eAAe,MAAM,gBAAgB,IAAI;AAAA,EACvD;AAEA,QAAM,WAA+B;AAAA,IACnC,CAAC,4BAA4B,GAAG,OAAO,WAAW,YAAY;AAAA,IAC9D;AAAA,IACA;AAAA,IACA,SAAS,WAAW,WAAW,CAAC;AAAA,IAChC,QAAQ,gBAAgB;AAAA,IACxB,QAAQ,WAAW,UAAU;AAAA,IAC7B,UAAU,WAAW,YAAY;AAAA,IACjC,QAAQ,OAAO,UAAU;AAAA,IACzB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,YAAY,wBAAwB,WAAW,UAAU;AAAA,IACzD,MAAM,kBAAkB,WAAW,IAAI;AAAA,IACvC,WAAW,uBAAuB,WAAW,SAAS;AAAA,IACtD,eAAe,WAAW,iBAAiB;AAAA,IAC3C,UAAU,0BAA0B,WAAW,UAAU,IAAI;AAAA,IAC7D,SAAS,WAAW,WAAW,CAAC;AAAA,IAChC,OAAO,WAAW,SAAS,CAAC;AAAA,IAC5B;AAAA,IACA,oBAAoB,WAAW,sBAAsB;AAAA,IACrD,cAAc;AAAA,MACZ,kBAAkB;AAAA,MAClB,eAAe;AAAA,MACf,GAAG,WAAW;AAAA,IAChB;AAAA,IACA,SAAS,CAAC,GAAG,0BAA0B,YAAY,GAAG,GAAI,WAAW,WAAW,CAAC,CAAE;AAAA,IACnF;AAAA,IACA,eAAe,WAAW,iBAAiB;AAAA,IAC3C,WAAW,6BAAM,CAAC,GAAG,WAAW,GAAG,kBAAkB,GAA1C;AAAA,IACX,UAAU,6BAAM,UAAN;AAAA,IACV,SAAS,6BAAM;AAAA,MACb,GAAG;AAAA,MACH,GAAG;AAAA,MACH,GAAI,iBAAiB,CAAC,EAAE,QAAQ,MAAM,SAAS,CAAC,cAAc,EAAE,CAAC,IAAI,CAAC;AAAA,IACxE,GAJS;AAAA,IAKT;AAAA,IACA,QAAQ,uBAAuB,WAAW,MAAM;AAAA,IAChD,aAAa,6BAA6B,WAAW,WAAW;AAAA,IAChE,WAAW,WAAW,aAAa;AAAA,IACnC,MAAM,sBAAsB,WAAW,MAAM,EAAE,MAAM,KAAK,CAAC;AAAA,IAC3D,SAAS;AAAA,MACP,SAAS;AAAA,MACT,OAAO;AAAA,MACP,OAAO;AAAA,MACP,aAAa;AAAA,MACb,SAAS;AAAA,MACT,SAAS,CAAC,EAAE,KAAK,yBAAyB,aAAa,qBAAqB,CAAC;AAAA,MAC7E,GAAG,WAAW;AAAA,IAChB;AAAA,IACA,YAAY,WAAW,cAAc,CAAC;AAAA,IACtC,UAAU,WAAW,YAAY,CAAC;AAAA,IAClC,SAAS,WAAW,YAAY,MAAM;AAAA,IACtC,eAAe,2BAA2B,WAAW,aAAa;AAAA,IAClE;AAAA,IACA;AAAA,IACA,QAAQ,WAAW,UAAU;AAAA,IAC7B,SAAS,WAAW,WAAW;AAAA,IAC/B;AAAA,IACA,UAAU,WAAW,YAAY;AAAA,IACjC,eAAe;AAAA,MACb,eAAe;AAAA,MACf,uBAAuB;AAAA,MACvB,GAAG,WAAW;AAAA,IAChB;AAAA,IACA,qBAAqB,WAAW,uBAAuB,CAAC;AAAA,IACxD,qBAAqB,WAAW,uBAAuB,CAAC;AAAA,IACxD;AAAA,IACA,YAAY;AAAA,MACV,cAAc;AAAA,MACd,mBAAmB;AAAA,MACnB,GAAG,WAAW;AAAA,IAChB;AAAA,IACA,MAAM,OAAO,WAAW,SAAS,aAAa,WAAW,KAAK,CAAC,CAAC,IAAI,WAAW,QAAQ,CAAC;AAAA,EAC1F;AAEA,SAAO;AACT;AA3IsB;AA6ItB,eAAsB,WACpB,SACA,YACA,OAAO,QAAQ,IAAI,aAAa,eAAe,eAAe,eAC9D,iBACqC;AACrC,QAAM,EAAE,WAAW,IAAI,MAAM,OAAO,IAAI;AACxC,QAAM,UAAU,oBAAoB,MAAM,OAAO,MAAM,GAAG;AAE1D,QAAM,OAAO,WAAW,QAAQ,IAAI;AACpC,QAAM,YAAY,QAAQ,MAAM,MAAM,EAAE;AACxC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,SAAS,GAAG;AACpD,QAAI,QAAQ,IAAI,GAAG,MAAM,QAAW;AAClC,cAAQ,IAAI,GAAG,IAAI;AAAA,IACrB;AAAA,EACF;AACA,QAAM,cAAc;AAAA,IAClB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,OAAO,OAAO;AAEhB,aAAW,gBAAgB,aAAa;AACtC,QAAI;AAEF,YAAM,eAAe,aAAa,WAAW,GAAG,IAC5C,eACA,KAAK,KAAK,MAAM,YAAY;AAGhC,YAAM,iBAAiB,KAAK,QAAQ,YAAY;AAGhD,UAAI,CAAC,WAAW,cAAc,GAAG;AAC/B;AAAA,MACF;AAEA,YAAM,eAAe,MAAM,mBAAmC,gBAAgB,EAAE,KAAK,CAAC;AACtF,aAAO,aAAa,SAAS,SAAY,EAAE,GAAG,cAAc,KAAK,IAAI;AAAA,IACvE,SAAS,OAAY;AACnB,YAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,YAAM,IAAI,MAAM,8BAA8B,YAAY,KAAK,OAAO,EAAE;AAAA,IAC1E;AAAA,EACF;AACA,SAAO;AACT;AAnDsB;","names":[]}