@stacksjs/stx 0.2.94 → 0.2.96

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 (614) hide show
  1. package/dist/a11y.js +598 -2
  2. package/dist/analytics.js +159 -2
  3. package/dist/analyzer.js +240 -2
  4. package/dist/animation.js +688 -2
  5. package/dist/app-shell.js +220 -2
  6. package/dist/app.js +79 -2
  7. package/dist/assets.js +155 -2
  8. package/dist/ast.js +630 -2
  9. package/dist/async-components.js +428 -2
  10. package/dist/auth.js +12 -2
  11. package/dist/broadcasting.js +102 -2
  12. package/dist/browser-composables.js +565 -2
  13. package/dist/build-assets.js +29 -2
  14. package/dist/build-mode-detector.js +50 -2
  15. package/dist/build-optimizer.js +433 -2
  16. package/dist/build-views.js +180 -2
  17. package/dist/build.js +33 -2
  18. package/dist/builtins/drawer.js +37 -2
  19. package/dist/builtins/escape.js +3 -2
  20. package/dist/builtins/icon.js +83 -2
  21. package/dist/builtins/index.js +34 -2
  22. package/dist/builtins/modal.js +38 -2
  23. package/dist/builtins/safe-image.js +51 -2
  24. package/dist/builtins/stx-image.js +200 -2
  25. package/dist/builtins/stx-link.js +41 -2
  26. package/dist/builtins/stx-loading-indicator.js +35 -2
  27. package/dist/builtins/suspense.js +24 -2
  28. package/dist/builtins/toast.js +42 -2
  29. package/dist/builtins/tooltip.js +106 -2
  30. package/dist/builtins/transition-group.js +22 -2
  31. package/dist/bundle-analyzer/collector.js +233 -2
  32. package/dist/bundle-analyzer/index.js +82 -2
  33. package/dist/bundle-analyzer/report.js +318 -2
  34. package/dist/bundle-analyzer/treemap.js +594 -2
  35. package/dist/caching.js +131 -2
  36. package/dist/cli.js +11317 -10982
  37. package/dist/client/directive.js +14 -2
  38. package/dist/client/index.js +2 -2
  39. package/dist/client-helpers.js +312 -2
  40. package/dist/client-script-bundler.js +216 -6
  41. package/dist/client-script.js +754 -2
  42. package/dist/client.js +73 -4
  43. package/dist/component-hmr.js +585 -2
  44. package/dist/component-library.d.ts +6 -0
  45. package/dist/component-library.js +683 -0
  46. package/dist/component-processing.js +613 -2
  47. package/dist/component-registry.js +90 -2
  48. package/dist/component-renderer.js +660 -2
  49. package/dist/components.js +213 -2
  50. package/dist/composables/index.js +220 -2
  51. package/dist/composables/use-battery.js +101 -2
  52. package/dist/composables/use-broadcast-channel.js +80 -2
  53. package/dist/composables/use-channel.js +124 -2
  54. package/dist/composables/use-clipboard.js +79 -2
  55. package/dist/composables/use-color-mode.js +131 -2
  56. package/dist/composables/use-cookie.js +86 -2
  57. package/dist/composables/use-device-orientation.js +181 -2
  58. package/dist/composables/use-event-listener.js +27 -2
  59. package/dist/composables/use-event-source.js +166 -2
  60. package/dist/composables/use-eye-dropper.js +142 -2
  61. package/dist/composables/use-fetch.js +223 -2
  62. package/dist/composables/use-fullscreen.js +110 -2
  63. package/dist/composables/use-geolocation.js +101 -2
  64. package/dist/composables/use-idle.js +182 -2
  65. package/dist/composables/use-intersection-observer.js +168 -2
  66. package/dist/composables/use-keyboard.js +224 -2
  67. package/dist/composables/use-media-query.js +62 -2
  68. package/dist/composables/use-meta.js +48 -2
  69. package/dist/composables/use-mouse.js +286 -2
  70. package/dist/composables/use-mutation-observer.js +129 -2
  71. package/dist/composables/use-network.js +85 -2
  72. package/dist/composables/use-notification.js +94 -2
  73. package/dist/composables/use-permissions.js +132 -2
  74. package/dist/composables/use-query.js +0 -1
  75. package/dist/composables/use-resize-observer.js +157 -2
  76. package/dist/composables/use-router.js +51 -2
  77. package/dist/composables/use-share.js +104 -2
  78. package/dist/composables/use-speech.js +294 -2
  79. package/dist/composables/use-storage.js +130 -2
  80. package/dist/composables/use-text-selection.js +205 -4
  81. package/dist/composables/use-timer.js +183 -2
  82. package/dist/composables/use-utilities.js +176 -2
  83. package/dist/composables/use-wake-lock.js +122 -2
  84. package/dist/composables/use-websocket.js +165 -2
  85. package/dist/composables/use-window.js +163 -2
  86. package/dist/composables.js +552 -2
  87. package/dist/composition-api.js +190 -2
  88. package/dist/computed.js +376 -8
  89. package/dist/conditionals.js +599 -2
  90. package/dist/config.js +751 -2
  91. package/dist/craft-bridge.js +432 -2
  92. package/dist/craft-compiler.js +810 -2
  93. package/dist/craft-components.js +945 -2
  94. package/dist/craft-entry.js +5 -2
  95. package/dist/craft-ssr.js +559 -2
  96. package/dist/csp.js +220 -2
  97. package/dist/csrf.js +38 -2
  98. package/dist/custom-directives.js +136 -2
  99. package/dist/defer.js +156 -2
  100. package/dist/deploy/config-generators.js +214 -2
  101. package/dist/deploy/index.js +203 -2
  102. package/dist/deploy/netlify.js +167 -2
  103. package/dist/dev-server/crosswind.js +379 -2
  104. package/dist/dev-server/index.js +7 -2
  105. package/dist/dev-server/keyboard-shortcuts.js +81 -2
  106. package/dist/dev-server/native-window.js +91 -2
  107. package/dist/dev-server/port-utils.js +40 -2
  108. package/dist/dev-server/serve-app.js +682 -7
  109. package/dist/dev-server/serve-file.js +439 -7
  110. package/dist/dev-server/serve-markdown.js +281 -2
  111. package/dist/dev-server/serve-multi.js +424 -17
  112. package/dist/dev-server/terminal-colors.js +45 -2
  113. package/dist/dev-server/theme-selector.js +111 -2
  114. package/dist/dev-server/types.js +43 -2
  115. package/dist/dev-server.js +4 -2
  116. package/dist/devtools.js +462 -18
  117. package/dist/directive-api.js +355 -2
  118. package/dist/docs.js +567 -2
  119. package/dist/doctor.js +123 -2
  120. package/dist/document-shell.js +105 -2
  121. package/dist/dynamic-components.js +78 -2
  122. package/dist/edge-runtime.js +539 -2
  123. package/dist/env.js +9 -2
  124. package/dist/error-boundaries.js +62 -12
  125. package/dist/error-handling.js +1 -2
  126. package/dist/errors/codes.js +97 -2
  127. package/dist/errors/formatter.js +196 -2
  128. package/dist/errors/index.js +44 -2
  129. package/dist/errors/logger.js +250 -2
  130. package/dist/errors/sanitizer.js +181 -2
  131. package/dist/errors/types.js +86 -2
  132. package/dist/events.js +382 -2
  133. package/dist/expressions.js +650 -2
  134. package/dist/formatter.js +265 -2
  135. package/dist/forms-validation.js +510 -4
  136. package/dist/forms.js +709 -2
  137. package/dist/head.js +224 -2
  138. package/dist/heatmap.js +566 -2
  139. package/dist/hot-reload.js +367 -2
  140. package/dist/html-masking.js +73 -2
  141. package/dist/hydration-runtime.js +195 -2
  142. package/dist/hydration.js +654 -2
  143. package/dist/i18n.js +633 -2
  144. package/dist/image-optimization/auto-sibling.js +88 -2
  145. package/dist/image-optimization/build-plugin.js +241 -2
  146. package/dist/image-optimization/component.js +244 -2
  147. package/dist/image-optimization/directive.js +203 -2
  148. package/dist/image-optimization/index.js +54 -2
  149. package/dist/image-optimization/processor.js +262 -2
  150. package/dist/image-optimization/serve.js +102 -2
  151. package/dist/includes.js +733 -2
  152. package/dist/index.d.ts +1 -0
  153. package/dist/index.js +134 -2
  154. package/dist/init.js +505 -2
  155. package/dist/inline-assets.js +82 -2
  156. package/dist/interactive.js +383 -2
  157. package/dist/internal-markdown.js +141 -2
  158. package/dist/island-chunking.js +52 -2
  159. package/dist/js-ts.js +57 -2
  160. package/dist/jsx-runtime.js +289 -2
  161. package/dist/keep-alive.js +421 -2
  162. package/dist/lazy-loader.js +245 -2
  163. package/dist/loading-indicator.js +322 -2
  164. package/dist/loops.js +643 -2
  165. package/dist/manifest.js +31 -2
  166. package/dist/markdown.js +68 -2
  167. package/dist/media/client/blur-up.js +217 -2
  168. package/dist/media/client/index.js +53 -2
  169. package/dist/media/client/lazy-load.js +283 -2
  170. package/dist/media/client/upload-handler.js +354 -2
  171. package/dist/media/image/component.js +574 -2
  172. package/dist/media/image/directive.js +160 -2
  173. package/dist/media/image/editing.js +193 -2
  174. package/dist/media/image/index.js +80 -2
  175. package/dist/media/image/placeholder.js +188 -2
  176. package/dist/media/image/processor/cache.js +51 -2
  177. package/dist/media/image/processor/index.js +3 -2
  178. package/dist/media/image/processor/optimizer.js +202 -2
  179. package/dist/media/image/processor/responsive.js +162 -2
  180. package/dist/media/image/srcset.js +194 -2
  181. package/dist/media/index.js +198 -2
  182. package/dist/media/manager/embed.js +253 -2
  183. package/dist/media/protected/component.js +235 -2
  184. package/dist/media/protected/index.js +20 -2
  185. package/dist/media/protected/signature.js +205 -2
  186. package/dist/media/shared/cache.js +132 -2
  187. package/dist/media/shared/hash.js +35 -2
  188. package/dist/media/shared/index.js +2 -2
  189. package/dist/media/types.js +0 -1
  190. package/dist/media/upload/component.js +320 -2
  191. package/dist/media/upload/index.js +1 -2
  192. package/dist/media/video/directive.js +142 -2
  193. package/dist/media/video/index.js +583 -2
  194. package/dist/media/video/processor/cache.js +52 -2
  195. package/dist/media/video/processor/index.js +4 -2
  196. package/dist/media/video/processor/streaming.js +197 -2
  197. package/dist/media/video/processor/thumbnail.js +134 -2
  198. package/dist/media/video/processor/transcoder.js +283 -2
  199. package/dist/method-spoofing.js +17 -2
  200. package/dist/middleware.js +40 -2
  201. package/dist/misc-directives.js +222 -2
  202. package/dist/native-build.js +511 -2
  203. package/dist/parser/directive-parser.js +239 -2
  204. package/dist/parser/expression-parser.js +358 -2
  205. package/dist/parser/index.js +23 -2
  206. package/dist/parser/tokenizer.js +534 -2
  207. package/dist/partial-hydration.js +427 -2
  208. package/dist/performance-utils.js +430 -2
  209. package/dist/placeholder.js +35 -2
  210. package/dist/plugin-system.js +214 -2
  211. package/dist/plugin.js +173 -2
  212. package/dist/precompiler.js +660 -81
  213. package/dist/process.js +711 -2
  214. package/dist/production-build.js +596 -2
  215. package/dist/production-builder.js +132 -2
  216. package/dist/production-server.js +188 -2
  217. package/dist/props.js +224 -2
  218. package/dist/public-env.js +19 -2
  219. package/dist/pwa/audit.js +255 -2
  220. package/dist/pwa/directives.js +332 -2
  221. package/dist/pwa/icons.js +109 -2
  222. package/dist/pwa/index.js +47 -2
  223. package/dist/pwa/inject.js +102 -2
  224. package/dist/pwa/manifest.js +186 -2
  225. package/dist/pwa/offline.js +259 -2
  226. package/dist/pwa/precache.js +116 -2
  227. package/dist/pwa/service-worker.js +860 -2
  228. package/dist/pwa/workbox-strategies.js +167 -2
  229. package/dist/pwa/workbox.js +382 -2
  230. package/dist/pwa.js +427 -427
  231. package/dist/reactive-bindings.js +266 -2
  232. package/dist/reactive.js +569 -2
  233. package/dist/reactivity.js +559 -2
  234. package/dist/release.js +1 -2
  235. package/dist/render.js +165 -2
  236. package/dist/route-middleware.js +17 -2
  237. package/dist/router.js +9 -2
  238. package/dist/routes.js +14 -2
  239. package/dist/runtime-injection.js +120 -2
  240. package/dist/runtime.js +94 -2
  241. package/dist/safe-evaluator.js +444 -2
  242. package/dist/scaffolding.js +897 -2
  243. package/dist/screenshot.js +87 -2
  244. package/dist/script-classifier.js +32 -2
  245. package/dist/script-validation.js +158 -2
  246. package/dist/seo.js +457 -2
  247. package/dist/serve.js +237 -2
  248. package/dist/server-bindings.js +108 -2
  249. package/dist/server-components.js +338 -11
  250. package/dist/signal-processing.js +946 -2
  251. package/dist/signals-api.js +154 -2
  252. package/dist/signals.js +5287 -2
  253. package/dist/site-builder/build.js +224 -2
  254. package/dist/site-builder/i18n.js +140 -2
  255. package/dist/site-builder/index.js +15 -2
  256. package/dist/site-builder/robots.js +26 -2
  257. package/dist/site-builder/router.js +27 -2
  258. package/dist/site-builder/seo.js +36 -2
  259. package/dist/site-builder/sitemap.js +26 -2
  260. package/dist/site-builder/theme.js +33 -2
  261. package/dist/site-builder/types.js +0 -1
  262. package/dist/slots.js +201 -2
  263. package/dist/source-maps.js +350 -2
  264. package/dist/spa-shell.js +34 -2
  265. package/dist/ssg.js +389 -389
  266. package/dist/ssr.js +355 -2
  267. package/dist/state-management.js +533 -2
  268. package/dist/store-imports.js +13 -2
  269. package/dist/store-loader.js +72 -5
  270. package/dist/stores-client.js +132 -2
  271. package/dist/story/addons.js +261 -2
  272. package/dist/story/analytics.js +235 -2
  273. package/dist/story/auto-stories.js +158 -2
  274. package/dist/story/bookmarks.js +277 -2
  275. package/dist/story/bun-test.js +102 -2
  276. package/dist/story/cli.js +155 -2
  277. package/dist/story/collect/analyzer.js +305 -2
  278. package/dist/story/collect/index.js +27 -2
  279. package/dist/story/collect/parser.js +129 -2
  280. package/dist/story/collect/scanner.js +101 -2
  281. package/dist/story/collect/tree.js +110 -2
  282. package/dist/story/commands/build.js +172 -2
  283. package/dist/story/commands/dev.js +78 -2
  284. package/dist/story/commands/index.js +3 -2
  285. package/dist/story/commands/preview.js +56 -2
  286. package/dist/story/compiled-output.js +151 -2
  287. package/dist/story/composition.js +261 -2
  288. package/dist/story/config-watcher.js +67 -2
  289. package/dist/story/config.js +64 -2
  290. package/dist/story/context.js +27 -2
  291. package/dist/story/controls/index.js +320 -2
  292. package/dist/story/crosswind.js +189 -2
  293. package/dist/story/desktop-preview.js +105 -2
  294. package/dist/story/docs-generator.js +186 -2
  295. package/dist/story/errors.js +239 -2
  296. package/dist/story/figma-export.js +224 -2
  297. package/dist/story/generator.js +165 -2
  298. package/dist/story/hmr.js +131 -2
  299. package/dist/story/hot-swap.js +207 -2
  300. package/dist/story/index.js +49 -2
  301. package/dist/story/interactions.js +225 -2
  302. package/dist/story/keyboard-shortcuts.js +345 -2
  303. package/dist/story/output.js +153 -2
  304. package/dist/story/performance.js +252 -2
  305. package/dist/story/presets.js +289 -2
  306. package/dist/story/props-validation.js +215 -2
  307. package/dist/story/renderer.js +209 -2
  308. package/dist/story/search-index.js +106 -2
  309. package/dist/story/search.js +140 -2
  310. package/dist/story/server.js +965 -2
  311. package/dist/story/setup.js +78 -2
  312. package/dist/story/snapshots.js +170 -2
  313. package/dist/story/testing.js +163 -2
  314. package/dist/story/theme.js +170 -2
  315. package/dist/story/types.js +0 -2
  316. package/dist/story/ui/code-panel.js +175 -2
  317. package/dist/story/ui/controls-panel.js +168 -2
  318. package/dist/story/ui/index.js +4 -2
  319. package/dist/story/ui/navigation.js +250 -2
  320. package/dist/story/ui/preview.js +251 -2
  321. package/dist/story/visual-testing.js +247 -2
  322. package/dist/streaming.js +537 -2
  323. package/dist/strict-lint.js +288 -2
  324. package/dist/style-scoping.js +50 -2
  325. package/dist/suspense.js +398 -2
  326. package/dist/teleport.js +109 -2
  327. package/dist/template-compiler.js +63 -2
  328. package/dist/template-hydrator.js +82 -2
  329. package/dist/template-tag-balance.js +93 -2
  330. package/dist/testing.js +581 -2
  331. package/dist/transitions.js +443 -2
  332. package/dist/type-checker.js +581 -2
  333. package/dist/types/component-types.d.ts +54 -0
  334. package/dist/types/component-types.js +0 -1
  335. package/dist/types/config-types.js +0 -1
  336. package/dist/types/context-types.js +0 -1
  337. package/dist/types/csp-types.js +0 -1
  338. package/dist/types/directive-types.js +3 -2
  339. package/dist/types/index.d.ts +5 -0
  340. package/dist/types/index.js +1 -2
  341. package/dist/types/pwa-types.js +0 -1
  342. package/dist/types.js +1 -2
  343. package/dist/typescript-templates.js +386 -4
  344. package/dist/utils.js +942 -2
  345. package/dist/validator.js +171 -2
  346. package/dist/variable-extractor.js +1094 -2
  347. package/dist/view-composers.js +29 -2
  348. package/dist/virtual-scrolling.js +454 -2
  349. package/dist/visual-editor.js +688 -28
  350. package/dist/vue-template.js +475 -2
  351. package/dist/web-components/css-scoping.js +177 -2
  352. package/dist/web-components/index.js +13 -2
  353. package/dist/web-components/reactive-generator.js +121 -56
  354. package/dist/web-components.js +1447 -2
  355. package/dist/x-element.js +17 -5
  356. package/package.json +6 -7
  357. package/dist/chunk-03c26pjz.js +0 -3
  358. package/dist/chunk-04mvcmcr.js +0 -106
  359. package/dist/chunk-05hgyyqc.js +0 -4
  360. package/dist/chunk-095s3972.js +0 -99
  361. package/dist/chunk-0b9w2w1y.js +0 -1
  362. package/dist/chunk-0dz85jrp.js +0 -3
  363. package/dist/chunk-0g4gece6.js +0 -4
  364. package/dist/chunk-0jd0pndq.js +0 -3
  365. package/dist/chunk-0jkwrcwj.js +0 -3
  366. package/dist/chunk-0m9tdm7t.js +0 -71
  367. package/dist/chunk-0qakwen3.js +0 -1
  368. package/dist/chunk-0qnz93q2.js +0 -3
  369. package/dist/chunk-0tatqxj2.js +0 -57
  370. package/dist/chunk-0wdar532.js +0 -102
  371. package/dist/chunk-13yz561y.js +0 -3
  372. package/dist/chunk-174z0cd0.js +0 -3
  373. package/dist/chunk-1mmykse5.js +0 -81
  374. package/dist/chunk-1z2yq9em.js +0 -3
  375. package/dist/chunk-1z5nhbjt.js +0 -90
  376. package/dist/chunk-1zgsgk4b.js +0 -1
  377. package/dist/chunk-25s7bckb.js +0 -171
  378. package/dist/chunk-268adc7r.js +0 -2230
  379. package/dist/chunk-26r6zh3t.js +0 -194
  380. package/dist/chunk-2w3302dh.js +0 -3
  381. package/dist/chunk-2xen423s.js +0 -3
  382. package/dist/chunk-39gm08bn.js +0 -39
  383. package/dist/chunk-3bjtemm6.js +0 -128
  384. package/dist/chunk-3jm3snz8.js +0 -3
  385. package/dist/chunk-3ngm57nt.js +0 -12
  386. package/dist/chunk-3rh7va1z.js +0 -3
  387. package/dist/chunk-3yg9hbmb.js +0 -4
  388. package/dist/chunk-44hd3kab.js +0 -1
  389. package/dist/chunk-46mkpbkk.js +0 -12
  390. package/dist/chunk-48cw2nde.js +0 -2
  391. package/dist/chunk-48r3qe0k.js +0 -3
  392. package/dist/chunk-4aj7ftqb.js +0 -1
  393. package/dist/chunk-4bt81cg3.js +0 -61
  394. package/dist/chunk-4j188175.js +0 -3
  395. package/dist/chunk-4k7d8p8d.js +0 -188
  396. package/dist/chunk-4qq8ffke.js +0 -28
  397. package/dist/chunk-50vqeesm.js +0 -142
  398. package/dist/chunk-52agge4n.js +0 -38
  399. package/dist/chunk-55yp0q8t.js +0 -201
  400. package/dist/chunk-57p201gb.js +0 -83
  401. package/dist/chunk-5ggw1dyv.js +0 -3
  402. package/dist/chunk-5kt3ay7x.js +0 -10
  403. package/dist/chunk-5p568px4.js +0 -1166
  404. package/dist/chunk-5ppkfyn2.js +0 -3
  405. package/dist/chunk-5q87fgkk.js +0 -3
  406. package/dist/chunk-5qb761h2.js +0 -3
  407. package/dist/chunk-5xvbq2gs.js +0 -30
  408. package/dist/chunk-647849kf.js +0 -34
  409. package/dist/chunk-6b5k6w2q.js +0 -7
  410. package/dist/chunk-6cr3eeh4.js +0 -23
  411. package/dist/chunk-6djgb0hr.js +0 -3
  412. package/dist/chunk-6dqzky7x.js +0 -35
  413. package/dist/chunk-6e4c6g46.js +0 -3
  414. package/dist/chunk-6w03t7h6.js +0 -3
  415. package/dist/chunk-6wn85hn6.js +0 -4
  416. package/dist/chunk-6y4gqs1q.js +0 -169
  417. package/dist/chunk-75rndzbd.js +0 -6
  418. package/dist/chunk-77tga15w.js +0 -3
  419. package/dist/chunk-7a51hkpf.js +0 -3
  420. package/dist/chunk-7b0xdy5h.js +0 -386
  421. package/dist/chunk-7cgmq685.js +0 -33
  422. package/dist/chunk-7dy588as.js +0 -6
  423. package/dist/chunk-7rvh2wwv.js +0 -721
  424. package/dist/chunk-7sm05m0j.js +0 -351
  425. package/dist/chunk-7sqdeqsw.js +0 -1
  426. package/dist/chunk-7xcfy2fn.js +0 -4
  427. package/dist/chunk-82t27pvd.js +0 -5
  428. package/dist/chunk-87kx8byz.js +0 -1115
  429. package/dist/chunk-8fgwhhb8.js +0 -6
  430. package/dist/chunk-8qbax8xn.js +0 -347
  431. package/dist/chunk-91s2hres.js +0 -8
  432. package/dist/chunk-94g3cahw.js +0 -11
  433. package/dist/chunk-957amb71.js +0 -8
  434. package/dist/chunk-95w08s8v.js +0 -3
  435. package/dist/chunk-9agvhp1x.js +0 -93
  436. package/dist/chunk-9tmbrwwx.js +0 -219
  437. package/dist/chunk-9yz5d003.js +0 -51
  438. package/dist/chunk-a3hyn4we.js +0 -79
  439. package/dist/chunk-a69tvya5.js +0 -53
  440. package/dist/chunk-adjcg6wa.js +0 -498
  441. package/dist/chunk-adqh2m9z.js +0 -45
  442. package/dist/chunk-asarebzq.js +0 -292
  443. package/dist/chunk-aw3rp9ac.js +0 -24
  444. package/dist/chunk-b0cyc09a.js +0 -109
  445. package/dist/chunk-b3kkjcdh.js +0 -3
  446. package/dist/chunk-b3prs7y0.js +0 -5
  447. package/dist/chunk-b5zc9y0y.js +0 -90
  448. package/dist/chunk-baa7h4yz.js +0 -3
  449. package/dist/chunk-bgec9r1v.js +0 -5224
  450. package/dist/chunk-bjnjpsgn.js +0 -3
  451. package/dist/chunk-bk8ew8ze.js +0 -24
  452. package/dist/chunk-bn08k7yy.js +0 -3
  453. package/dist/chunk-bpgg59wa.js +0 -3
  454. package/dist/chunk-bwxda6n1.js +0 -3
  455. package/dist/chunk-bykjk6vj.js +0 -4
  456. package/dist/chunk-c53hyw5c.js +0 -477
  457. package/dist/chunk-c7jg8w13.js +0 -3
  458. package/dist/chunk-ca6qd1dx.js +0 -3
  459. package/dist/chunk-cdbwprfv.js +0 -6
  460. package/dist/chunk-ceg2c2q2.js +0 -11
  461. package/dist/chunk-cn409b69.js +0 -3
  462. package/dist/chunk-cn8az1b4.js +0 -1
  463. package/dist/chunk-cp3kwv17.js +0 -8
  464. package/dist/chunk-cpcc11vp.js +0 -5
  465. package/dist/chunk-cr3wbrcr.js +0 -10
  466. package/dist/chunk-cygfdk1n.js +0 -3
  467. package/dist/chunk-cyp4m0vh.js +0 -16
  468. package/dist/chunk-cz25azze.js +0 -4
  469. package/dist/chunk-d77yxcds.js +0 -3
  470. package/dist/chunk-dvfs1h3c.js +0 -117
  471. package/dist/chunk-dyjnn5k8.js +0 -262
  472. package/dist/chunk-dzw95th7.js +0 -3
  473. package/dist/chunk-e0zytzdh.js +0 -179
  474. package/dist/chunk-e53h9qhd.js +0 -84
  475. package/dist/chunk-eds0f8f1.js +0 -3
  476. package/dist/chunk-eh8hact1.js +0 -5
  477. package/dist/chunk-epj957jf.js +0 -4
  478. package/dist/chunk-eqeyaq6g.js +0 -77
  479. package/dist/chunk-fbxt2mrx.js +0 -5
  480. package/dist/chunk-fch9tk1k.js +0 -3
  481. package/dist/chunk-fe7r1mq1.js +0 -9
  482. package/dist/chunk-fhawx87n.js +0 -8
  483. package/dist/chunk-fk51yyrw.js +0 -3
  484. package/dist/chunk-fms20x0n.js +0 -21
  485. package/dist/chunk-fs0qezn5.js +0 -341
  486. package/dist/chunk-fzm3y0r3.js +0 -267
  487. package/dist/chunk-g2hekckm.js +0 -161
  488. package/dist/chunk-g4ps1dj8.js +0 -140
  489. package/dist/chunk-g8b81pzc.js +0 -3
  490. package/dist/chunk-ganag9dm.js +0 -3
  491. package/dist/chunk-gc84b1d2.js +0 -58
  492. package/dist/chunk-gcf5v18y.js +0 -60
  493. package/dist/chunk-ghrx0hn1.js +0 -4
  494. package/dist/chunk-gqpkp459.js +0 -3
  495. package/dist/chunk-h45py5w5.js +0 -2
  496. package/dist/chunk-h5wa62ek.js +0 -145
  497. package/dist/chunk-h82kjdr4.js +0 -83
  498. package/dist/chunk-haecq01c.js +0 -3
  499. package/dist/chunk-hepg894w.js +0 -3
  500. package/dist/chunk-hjdc99kb.js +0 -3
  501. package/dist/chunk-hje9v2zh.js +0 -3
  502. package/dist/chunk-hjv76kcw.js +0 -1
  503. package/dist/chunk-hke99a0v.js +0 -3
  504. package/dist/chunk-hpqr9e3x.js +0 -3
  505. package/dist/chunk-hq5cem49.js +0 -236
  506. package/dist/chunk-hrampcrj.js +0 -3
  507. package/dist/chunk-ht4j68cs.js +0 -3
  508. package/dist/chunk-hxx3za24.js +0 -62
  509. package/dist/chunk-j4s5qwd7.js +0 -4
  510. package/dist/chunk-jbejwejg.js +0 -8
  511. package/dist/chunk-jc0fc4ht.js +0 -11
  512. package/dist/chunk-jcs0ymw7.js +0 -3
  513. package/dist/chunk-jfm69keq.js +0 -231
  514. package/dist/chunk-jfrn43vh.js +0 -2
  515. package/dist/chunk-jjamhxpm.js +0 -139
  516. package/dist/chunk-jjvp4t5w.js +0 -27
  517. package/dist/chunk-jt44av4j.js +0 -3
  518. package/dist/chunk-jt98jhpt.js +0 -10
  519. package/dist/chunk-k8440jxh.js +0 -6
  520. package/dist/chunk-kdxa9epn.js +0 -21
  521. package/dist/chunk-kfd2hf6f.js +0 -3
  522. package/dist/chunk-kgym7ch9.js +0 -8
  523. package/dist/chunk-kh6rfz2v.js +0 -4
  524. package/dist/chunk-kkp6rs2n.js +0 -36
  525. package/dist/chunk-ktkmvaa8.js +0 -1
  526. package/dist/chunk-m59y310j.js +0 -3
  527. package/dist/chunk-mgmyr1b9.js +0 -6
  528. package/dist/chunk-mqwbpamc.js +0 -3
  529. package/dist/chunk-mrehzhxv.js +0 -5
  530. package/dist/chunk-mv03qb75.js +0 -3
  531. package/dist/chunk-mv4fb50w.js +0 -1
  532. package/dist/chunk-mwbng54r.js +0 -2
  533. package/dist/chunk-n46a5g1g.js +0 -3
  534. package/dist/chunk-n944baxp.js +0 -3
  535. package/dist/chunk-nanw7yhz.js +0 -14
  536. package/dist/chunk-nap11ntr.js +0 -21
  537. package/dist/chunk-ncnfa8ae.js +0 -29
  538. package/dist/chunk-ngxfwzq3.js +0 -3
  539. package/dist/chunk-nvwb4x04.js +0 -3
  540. package/dist/chunk-nw34xajc.js +0 -8
  541. package/dist/chunk-payfb24w.js +0 -207
  542. package/dist/chunk-pc31m5x5.js +0 -398
  543. package/dist/chunk-pg1fvqb9.js +0 -167
  544. package/dist/chunk-q60knhjf.js +0 -3
  545. package/dist/chunk-q6h6yvzb.js +0 -10
  546. package/dist/chunk-qd5461tt.js +0 -3
  547. package/dist/chunk-qdc3aav1.js +0 -3
  548. package/dist/chunk-qfwzdffx.js +0 -3
  549. package/dist/chunk-qgxwmagw.js +0 -134
  550. package/dist/chunk-qhdtssn1.js +0 -19
  551. package/dist/chunk-qk584whs.js +0 -3
  552. package/dist/chunk-qm4yppj5.js +0 -57
  553. package/dist/chunk-qwyd9a1d.js +0 -2
  554. package/dist/chunk-qxs6et76.js +0 -196
  555. package/dist/chunk-rb1e4cnb.js +0 -3
  556. package/dist/chunk-rh80q1nd.js +0 -1
  557. package/dist/chunk-rkffm9sy.js +0 -128
  558. package/dist/chunk-rv002yn0.js +0 -14
  559. package/dist/chunk-s6ja2bdg.js +0 -66
  560. package/dist/chunk-sjagg9qz.js +0 -66
  561. package/dist/chunk-sn07azv3.js +0 -3
  562. package/dist/chunk-svahbw0w.js +0 -12
  563. package/dist/chunk-svhtdb0s.js +0 -6
  564. package/dist/chunk-t37dp99j.js +0 -3
  565. package/dist/chunk-tj6zfxeb.js +0 -64
  566. package/dist/chunk-tmgz5t2g.js +0 -3
  567. package/dist/chunk-tr0z0e1g.js +0 -3
  568. package/dist/chunk-tx6br9r4.js +0 -274
  569. package/dist/chunk-v97390pe.js +0 -1
  570. package/dist/chunk-vcr5pzpx.js +0 -233
  571. package/dist/chunk-vdfwv0fp.js +0 -6
  572. package/dist/chunk-vp2395eb.js +0 -3
  573. package/dist/chunk-vpe6napb.js +0 -28
  574. package/dist/chunk-vv9wfz1c.js +0 -12
  575. package/dist/chunk-vw6ejgmy.js +0 -21
  576. package/dist/chunk-vx22he47.js +0 -1
  577. package/dist/chunk-w01y57f5.js +0 -1539
  578. package/dist/chunk-w21mwxdd.js +0 -4
  579. package/dist/chunk-w4n8fqp7.js +0 -216
  580. package/dist/chunk-w959hm8j.js +0 -358
  581. package/dist/chunk-wf7zrjsw.js +0 -138
  582. package/dist/chunk-wk07pwtd.js +0 -321
  583. package/dist/chunk-wvef3ngh.js +0 -127
  584. package/dist/chunk-wxvyj65q.js +0 -2
  585. package/dist/chunk-x1hjv24z.js +0 -11
  586. package/dist/chunk-x39sfpvm.js +0 -302
  587. package/dist/chunk-x4fze3q2.js +0 -314
  588. package/dist/chunk-x64kb787.js +0 -15
  589. package/dist/chunk-xcb0pbr6.js +0 -4
  590. package/dist/chunk-xhkjhxsp.js +0 -3
  591. package/dist/chunk-xhnpsngj.js +0 -5
  592. package/dist/chunk-xsqbk4yk.js +0 -3
  593. package/dist/chunk-xygc53vr.js +0 -68
  594. package/dist/chunk-y0qg6rrv.js +0 -3
  595. package/dist/chunk-y25pr13j.js +0 -19
  596. package/dist/chunk-y4c744dk.js +0 -3
  597. package/dist/chunk-y4md9hp0.js +0 -3
  598. package/dist/chunk-y5wazw6j.js +0 -7
  599. package/dist/chunk-y5xz0jc4.js +0 -141
  600. package/dist/chunk-y86m1wr4.js +0 -4
  601. package/dist/chunk-yaan98dd.js +0 -3
  602. package/dist/chunk-yach037f.js +0 -32
  603. package/dist/chunk-yexjrg9d.js +0 -7
  604. package/dist/chunk-ygvyc6wv.js +0 -90
  605. package/dist/chunk-yj560gp8.js +0 -8
  606. package/dist/chunk-yn38c15w.js +0 -4
  607. package/dist/chunk-yr1gdceh.js +0 -3
  608. package/dist/chunk-yw2fzq86.js +0 -3
  609. package/dist/chunk-ywkrxp2h.js +0 -147
  610. package/dist/chunk-z37xq5rx.js +0 -3
  611. package/dist/chunk-z4djtgt0.js +0 -71
  612. package/dist/chunk-z8cjr9n9.js +0 -7
  613. package/dist/chunk-znxp3zha.js +0 -71
  614. package/dist/chunk-zt2yag10.js +0 -429
package/dist/forms.js CHANGED
@@ -1,2 +1,709 @@
1
- // @bun
2
- import{$v as n,Ov as a,Pv as b,Qv as c,Rv as d,Sv as e,Tv as f,Uv as g,Vv as h,Wv as i,Xv as j,Yv as k,Zv as l,_v as m}from"./chunk-0tatqxj2.js";import"./chunk-adqh2m9z.js";import"./chunk-3jm3snz8.js";export{l as validateValueEnhanced,m as validateFormEnhanced,h as validateFields,g as validateField,f as registerValidationRule,k as registerEnhancedValidationRule,i as processValidateDirective,b as processForms,d as processFormInputDirectives,e as processErrorDirective,c as processBasicFormDirectives,n as generateValidationScript,j as enhancedValidationRules,a as defaultFormClasses};
1
+ import crypto from "node:crypto";
2
+ import { isExpressionSafe, safeEvaluate } from "./safe-evaluator.js";
3
+ function escapeAttr(str) {
4
+ return String(str ?? "").replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
5
+ }
6
+ export const defaultFormClasses = {
7
+ input: "form-control",
8
+ inputError: "is-invalid",
9
+ checkInput: "form-check-input",
10
+ label: "form-label",
11
+ errorFeedback: "invalid-feedback"
12
+ };
13
+ function getFormClasses(options) {
14
+ return {
15
+ ...defaultFormClasses,
16
+ ...options.forms?.classes
17
+ };
18
+ }
19
+ function buildClassString(existingClass, defaultClass, hasError, errorClass) {
20
+ const baseClass = existingClass || defaultClass;
21
+ return hasError ? `${baseClass} ${errorClass}` : baseClass;
22
+ }
23
+ function genId() {
24
+ return crypto.randomUUID();
25
+ }
26
+ export function processForms(template, context, _filePath, options) {
27
+ const classes = getFormClasses(options);
28
+ let output = template;
29
+ output = processValidateDirective(output, context);
30
+ output = processBasicFormDirectives(output, context);
31
+ output = processFormInputDirectives(output, context, classes);
32
+ output = processErrorDirective(output, context, classes);
33
+ return output;
34
+ }
35
+ export function processBasicFormDirectives(template, context) {
36
+ let result = template;
37
+ result = result.replace(/@csrf/g, () => {
38
+ if (!context.csrf || typeof context.csrf !== "object") {
39
+ const token = genId();
40
+ context.csrf = { token };
41
+ }
42
+ if (context.csrf.field)
43
+ return context.csrf.field;
44
+ if (context.csrf.token)
45
+ return `<input type="hidden" name="_token" value="${escapeAttr(context.csrf.token)}">`;
46
+ return '<input type="hidden" name="_token" value="">';
47
+ });
48
+ result = result.replace(/@method\(['"]([^'"]+)['"]\)/g, (match, method) => {
49
+ const upperMethod = method.toUpperCase();
50
+ if (method && !["GET", "POST"].includes(upperMethod))
51
+ return `<input type="hidden" name="_method" value="${escapeAttr(upperMethod)}">`;
52
+ return match;
53
+ });
54
+ return result;
55
+ }
56
+ export function processFormInputDirectives(template, context, classes = defaultFormClasses) {
57
+ let result = template;
58
+ result = result.replace(/@form\(\s*(?:(?:'([^']+)'|"([^"]+)")\s*)?(?:,\s*(?:'([^']+)'|"([^"]+)")?)?\s*(?:,\s*\{([^}]+)\}\s*)?\)/g, (_match, singleQuoteMethod, doubleQuoteMethod, singleQuoteAction, doubleQuoteAction, attributes = "") => {
59
+ const method = singleQuoteMethod || doubleQuoteMethod || "POST", action = singleQuoteAction || doubleQuoteAction || "", attrs = parseAttributes(attributes), methodStr = method.toUpperCase(), htmlMethod = ["GET", "POST"].includes(methodStr) ? methodStr : "POST";
60
+ let formHtml = `<form method="${escapeAttr(htmlMethod)}" action="${escapeAttr(action)}"${attrs ? ` ${attrs}` : ""}>`;
61
+ formHtml += `
62
+ ${processBasicFormDirectives("@csrf", context)}`;
63
+ if (!["GET", "POST"].includes(methodStr))
64
+ formHtml += `
65
+ ${processBasicFormDirectives(`@method('${methodStr}')`, context)}`;
66
+ return formHtml;
67
+ });
68
+ result = result.replace(/@endform/g, "</form>");
69
+ result = result.replace(/@input\(\s*(?:'([^']+)'|"([^"]+)")\s*(?:,\s*(?:(?:'([^']*)'|"([^"]*)")\s*)?)?(?:,\s*\{([^}]+)\})?\s*\)/g, (_match, singleQuoteName, doubleQuoteName, singleQuoteValue, doubleQuoteValue, attributes = "") => {
70
+ const name = singleQuoteName || doubleQuoteName || "", value = singleQuoteValue || doubleQuoteValue || "", attrs = parseAttributes(attributes), rawOldValue = getOldValue(name, context), oldValue = rawOldValue !== void 0 && rawOldValue !== null ? rawOldValue : value || "", typeMatch = attrs.match(/type=['"]([^'"]+)['"]/i), type = typeMatch ? typeMatch[1] : "text", hasError = hasFieldError(name, context), classMatch = attrs.match(/class=['"]([^'"]+)['"]/i), className = buildClassString(classMatch ? classMatch[1] : "", classes.input, hasError, classes.inputError);
71
+ let attrsWithoutClassAndType = attrs.replace(/class=['"][^'"]+['"]/i, "");
72
+ attrsWithoutClassAndType = attrsWithoutClassAndType.replace(/type=['"][^'"]+['"]/i, "");
73
+ return `<input type="${escapeAttr(type)}" name="${escapeAttr(name)}" value="${escapeAttr(oldValue)}" class="${className}"${attrsWithoutClassAndType ? ` ${attrsWithoutClassAndType}` : ""}>`;
74
+ });
75
+ result = result.replace(/@textarea\(\s*['"]([^'"]+)['"]\s*(?:,\s*\{([^}]+)\})?\)([\s\S]*?)@endtextarea/g, (_match, name, attributes = "", content = "") => {
76
+ const attrs = parseAttributes(attributes), oldValue = getOldValue(name, context) || content.trim(), hasError = hasFieldError(name, context), classMatch = attrs.match(/class=['"]([^'"]+)['"]/i), className = buildClassString(classMatch ? classMatch[1] : "", classes.input, hasError, classes.inputError), attrsWithoutClass = attrs.replace(/class=['"][^'"]+['"]/i, "");
77
+ return `<textarea name="${escapeAttr(name)}" class="${className}"${attrsWithoutClass ? ` ${attrsWithoutClass}` : ""}>${escapeAttr(oldValue)}</textarea>`;
78
+ });
79
+ result = result.replace(/@select\(\s*['"]([^'"]+)['"]\s*(?:,\s*\{([^}]+)\})?\)([\s\S]*?)@endselect/g, (_match, name, attributes = "", content) => {
80
+ const attrs = parseAttributes(attributes), oldValue = getOldValue(name, context), hasError = hasFieldError(name, context), classMatch = attrs.match(/class=['"]([^'"]+)['"]/i), className = buildClassString(classMatch ? classMatch[1] : "", classes.input, hasError, classes.inputError), attrsWithoutClass = attrs.replace(/class=['"][^'"]+['"]/i, "");
81
+ let processedContent = content;
82
+ if (oldValue !== void 0)
83
+ processedContent = content.replace(/(<option[^>]*value=['"]([^'"]+)['"][^>]*>)/gi, (optionMatch, optionTag, optionValue) => {
84
+ if ((Array.isArray(oldValue) ? oldValue.some((v) => String(v) === optionValue) : String(oldValue) === optionValue) && !optionTag.includes("selected"))
85
+ return optionTag.replace(/(<option)/, "$1 selected");
86
+ return optionMatch;
87
+ });
88
+ return `<select name="${escapeAttr(name)}" class="${className}"${attrsWithoutClass ? ` ${attrsWithoutClass}` : ""}>${processedContent}</select>`;
89
+ });
90
+ result = result.replace(/@checkbox\(\s*['"]([^'"]+)['"]\s*(?:,\s*['"]([^'"]+)['"]\s*)?(?:,\s*\{([^}]+)\})?\)/g, (_match, name, value = "1", attributes = "") => {
91
+ const attrs = parseAttributes(attributes), oldValues = getOldValue(name, context), isChecked = oldValues !== void 0 && (Array.isArray(oldValues) ? oldValues.some((v) => String(v) === value) : oldValues === !0 || String(oldValues) === value), classMatch = attrs.match(/class=['"]([^'"]+)['"]/i), className = classMatch ? classMatch[1] : classes.checkInput, attrsWithoutClass = attrs.replace(/class=['"][^'"]+['"]/i, "");
92
+ return `<input type="checkbox" name="${escapeAttr(name)}" value="${escapeAttr(value)}" class="${className}"${isChecked ? " checked" : ""}${attrsWithoutClass ? ` ${attrsWithoutClass}` : ""}>`;
93
+ });
94
+ result = result.replace(/@radio\(\s*['"]([^'"]+)['"]\s*,\s*['"]([^'"]+)['"]\s*(?:,\s*\{([^}]+)\})?\)/g, (_match, name, value, attributes = "") => {
95
+ const attrs = parseAttributes(attributes), oldValue = getOldValue(name, context), isChecked = oldValue !== void 0 && oldValue === value, classMatch = attrs.match(/class=['"]([^'"]+)['"]/i), className = classMatch ? classMatch[1] : classes.checkInput, attrsWithoutClass = attrs.replace(/class=['"][^'"]+['"]/i, "");
96
+ return `<input type="radio" name="${escapeAttr(name)}" value="${escapeAttr(value)}" class="${className}"${isChecked ? " checked" : ""}${attrsWithoutClass ? ` ${attrsWithoutClass}` : ""}>`;
97
+ });
98
+ result = result.replace(/@file\(\s*['"]([^'"]+)['"]\s*(?:,\s*\{([^}]+)\})?\)/g, (_match, name, attributes = "") => {
99
+ const attrs = parseAttributes(attributes), acceptMatch = attrs.match(/accept=['"]([^'"]+)['"]/i), accept = acceptMatch ? acceptMatch[1] : "", isMultiple = attrs.includes("multiple"), hasError = hasFieldError(name, context), classMatch = attrs.match(/class=['"]([^'"]+)['"]/i), className = buildClassString(classMatch ? classMatch[1] : "", classes.input, hasError, classes.inputError), attrsWithoutHandled = attrs.replace(/class=['"][^'"]+['"]/gi, "").replace(/accept=['"][^'"]+['"]/gi, "").replace(/\bmultiple\b/gi, "").trim(), parts = [
100
+ `<input type="file" name="${escapeAttr(name)}"`,
101
+ `class="${className}"`
102
+ ];
103
+ if (accept)
104
+ parts.push(`accept="${escapeAttr(accept)}"`);
105
+ if (isMultiple)
106
+ parts.push("multiple");
107
+ if (attrsWithoutHandled)
108
+ parts.push(attrsWithoutHandled);
109
+ return `${parts.join(" ")}>`;
110
+ });
111
+ result = result.replace(/@label\(\s*['"]([^'"]+)['"]\s*(?:,\s*\{([^}]+)\})?\)([\s\S]*?)@endlabel/g, (_match, forAttr, attributes = "", content) => {
112
+ const attrs = parseAttributes(attributes), classMatch = attrs.match(/class=['"]([^'"]+)['"]/i), className = classMatch ? classMatch[1] : classes.label, attrsWithoutClass = attrs.replace(/class=['"][^'"]+['"]/i, "");
113
+ return `<label for="${escapeAttr(forAttr)}" class="${className}"${attrsWithoutClass ? ` ${attrsWithoutClass}` : ""}>${content}</label>`;
114
+ });
115
+ return result;
116
+ }
117
+ export function processErrorDirective(template, context, _classes = defaultFormClasses) {
118
+ return template.replace(/@error\(['"]([^'"]+)['"]\)([\s\S]*?)@enderror/g, (match, field, content) => {
119
+ try {
120
+ if (hasFieldError(field, context))
121
+ return content.replace(/\{\{([^}]+)\}\}/g, (_, expr) => {
122
+ try {
123
+ if (expr.trim() === "$message" || expr.trim() === "message")
124
+ return getErrorMessage(field, context);
125
+ if (expr.trim().includes("errors.first") || expr.trim().includes("$errors.first")) {
126
+ if (typeof context.errors?.first === "function")
127
+ return context.errors.first(field);
128
+ return getErrorMessage(field, context);
129
+ }
130
+ const trimmedExpr = expr.trim();
131
+ if (isExpressionSafe(trimmedExpr)) {
132
+ const result = safeEvaluate(trimmedExpr, context);
133
+ return result !== void 0 ? String(result) : trimmedExpr;
134
+ }
135
+ return trimmedExpr;
136
+ } catch {
137
+ return expr;
138
+ }
139
+ });
140
+ return "";
141
+ } catch (error) {
142
+ console.error("Error processing @error directive:", error);
143
+ return match;
144
+ }
145
+ });
146
+ }
147
+ function hasFieldError(field, context) {
148
+ if (!context.errors)
149
+ return !1;
150
+ if (typeof context.errors.has === "function")
151
+ return context.errors.has(field);
152
+ if (typeof context.errors === "object")
153
+ return Object.prototype.hasOwnProperty.call(context.errors, field);
154
+ return !1;
155
+ }
156
+ function getErrorMessage(field, context) {
157
+ if (!context.errors)
158
+ return "";
159
+ if (typeof context.errors.get === "function")
160
+ return context.errors.get(field);
161
+ if (typeof context.errors === "object" && Object.prototype.hasOwnProperty.call(context.errors, field)) {
162
+ const error = context.errors[field];
163
+ return Array.isArray(error) ? error[0] : String(error);
164
+ }
165
+ return "";
166
+ }
167
+ function getOldValue(field, context) {
168
+ let value;
169
+ if (context.old && typeof context.old === "function")
170
+ return context.old(field);
171
+ if (context.old && typeof context.old === "object")
172
+ return context.old[field];
173
+ if (field.endsWith("[]")) {
174
+ const baseName = field.slice(0, -2);
175
+ value = context[baseName];
176
+ if (value !== void 0)
177
+ return value;
178
+ }
179
+ return context[field];
180
+ }
181
+ function parseAttributes(attributesStr) {
182
+ if (!attributesStr.trim())
183
+ return "";
184
+ const attrs = [], trimmed = attributesStr.trim(), attrRegex = /([\w-]+)\s*:\s*(['"]?)([^,'"]*)\2(?:\s*,\s*|\s*$)/g;
185
+ let match;
186
+ while ((match = attrRegex.exec(trimmed)) !== null) {
187
+ const [, name, , value] = match;
188
+ attrs.push(`${name}="${value.trim()}"`);
189
+ }
190
+ return attrs.join(" ");
191
+ }
192
+ const validationRules = {
193
+ required: (value, _params, field) => {
194
+ if (value === void 0 || value === null || value === "" || Array.isArray(value) && value.length === 0)
195
+ return `The ${field} field is required.`;
196
+ return null;
197
+ },
198
+ email: (value, _params, field) => {
199
+ if (!value)
200
+ return null;
201
+ if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(String(value)))
202
+ return `The ${field} field must be a valid email address.`;
203
+ return null;
204
+ },
205
+ min: (value, params, field) => {
206
+ if (!value)
207
+ return null;
208
+ const min = Number(params[0]);
209
+ if (typeof value === "string" && value.length < min)
210
+ return `The ${field} field must be at least ${min} characters.`;
211
+ if (typeof value === "number" && value < min)
212
+ return `The ${field} field must be at least ${min}.`;
213
+ if (Array.isArray(value) && value.length < min)
214
+ return `The ${field} field must have at least ${min} items.`;
215
+ return null;
216
+ },
217
+ max: (value, params, field) => {
218
+ if (!value)
219
+ return null;
220
+ const max = Number(params[0]);
221
+ if (typeof value === "string" && value.length > max)
222
+ return `The ${field} field must not exceed ${max} characters.`;
223
+ if (typeof value === "number" && value > max)
224
+ return `The ${field} field must not exceed ${max}.`;
225
+ if (Array.isArray(value) && value.length > max)
226
+ return `The ${field} field must not have more than ${max} items.`;
227
+ return null;
228
+ },
229
+ confirmed: (value, params, field) => {
230
+ if (params[0] !== void 0 && value !== params[0])
231
+ return `The ${field} confirmation does not match.`;
232
+ return null;
233
+ },
234
+ numeric: (value, _params, field) => {
235
+ if (!value)
236
+ return null;
237
+ if (Number.isNaN(Number(value)))
238
+ return `The ${field} field must be a number.`;
239
+ return null;
240
+ },
241
+ integer: (value, _params, field) => {
242
+ if (!value)
243
+ return null;
244
+ if (!Number.isInteger(Number(value)))
245
+ return `The ${field} field must be an integer.`;
246
+ return null;
247
+ },
248
+ alpha: (value, _params, field) => {
249
+ if (!value)
250
+ return null;
251
+ if (!/^[a-z]+$/i.test(String(value)))
252
+ return `The ${field} field must only contain letters.`;
253
+ return null;
254
+ },
255
+ alphanumeric: (value, _params, field) => {
256
+ if (!value)
257
+ return null;
258
+ if (!/^[a-z0-9]+$/i.test(String(value)))
259
+ return `The ${field} field must only contain letters and numbers.`;
260
+ return null;
261
+ },
262
+ url: (value, _params, field) => {
263
+ if (!value)
264
+ return null;
265
+ try {
266
+ return new URL(String(value)) ? null : null;
267
+ } catch {
268
+ return `The ${field} field must be a valid URL.`;
269
+ }
270
+ },
271
+ regex: (value, params, field) => {
272
+ if (!value)
273
+ return null;
274
+ try {
275
+ if (!new RegExp(params[0]).test(String(value)))
276
+ return `The ${field} field format is invalid.`;
277
+ return null;
278
+ } catch {
279
+ return `The ${field} field has an invalid validation pattern.`;
280
+ }
281
+ },
282
+ in: (value, params, field) => {
283
+ if (!value)
284
+ return null;
285
+ if (!params.includes(String(value)))
286
+ return `The ${field} field must be one of: ${params.join(", ")}.`;
287
+ return null;
288
+ },
289
+ notIn: (value, params, field) => {
290
+ if (!value)
291
+ return null;
292
+ if (params.includes(String(value)))
293
+ return `The ${field} field must not be: ${params.join(", ")}.`;
294
+ return null;
295
+ },
296
+ date: (value, _params, field) => {
297
+ if (!value)
298
+ return null;
299
+ const date = new Date(value);
300
+ if (Number.isNaN(date.getTime()))
301
+ return `The ${field} field must be a valid date.`;
302
+ return null;
303
+ },
304
+ before: (value, params, field) => {
305
+ if (!value)
306
+ return null;
307
+ const date = new Date(value), beforeDate = new Date(params[0]);
308
+ if (date >= beforeDate)
309
+ return `The ${field} field must be before ${params[0]}.`;
310
+ return null;
311
+ },
312
+ after: (value, params, field) => {
313
+ if (!value)
314
+ return null;
315
+ const date = new Date(value), afterDate = new Date(params[0]);
316
+ if (date <= afterDate)
317
+ return `The ${field} field must be after ${params[0]}.`;
318
+ return null;
319
+ }
320
+ };
321
+ export function registerValidationRule(name, validator) {
322
+ validationRules[name] = validator;
323
+ }
324
+ function parseValidationRule(ruleStr) {
325
+ const [name, ...paramParts] = ruleStr.split(":"), params = paramParts.length > 0 ? paramParts.join(":").split(",") : [];
326
+ return { name: name.trim(), params };
327
+ }
328
+ export function validateField(field, value, rules, context = {}) {
329
+ const errors = [], ruleList = rules.split("|").map((r) => r.trim()).filter(Boolean);
330
+ for (const ruleStr of ruleList) {
331
+ const rule = parseValidationRule(ruleStr), validator = validationRules[rule.name];
332
+ if (!validator) {
333
+ console.warn(`Unknown validation rule: ${rule.name}`);
334
+ continue;
335
+ }
336
+ if (rule.name === "confirmed") {
337
+ const confirmField = `${field}_confirmation`;
338
+ rule.params = [context[confirmField]];
339
+ }
340
+ const error = validator(value, rule.params || [], field);
341
+ if (error)
342
+ errors.push(rule.message || error);
343
+ }
344
+ return {
345
+ field,
346
+ valid: errors.length === 0,
347
+ errors
348
+ };
349
+ }
350
+ export function validateFields(data, rules) {
351
+ const errors = {};
352
+ for (const [field, fieldRules] of Object.entries(rules)) {
353
+ const result = validateField(field, data[field], fieldRules, data);
354
+ if (!result.valid)
355
+ errors[field] = result.errors;
356
+ }
357
+ return errors;
358
+ }
359
+ export function processValidateDirective(template, _context) {
360
+ return template.replace(/@validate\(\s*['"]([^'"]+)['"]\s*,\s*['"]([^'"]+)['"]\s*(?:,\s*\{([^}]*)\})?\s*\)/g, (_match, field, rules, _options) => {
361
+ const ruleList = rules.split("|").map((r) => r.trim()), attrs = [];
362
+ for (const ruleStr of ruleList) {
363
+ const rule = parseValidationRule(ruleStr);
364
+ switch (rule.name) {
365
+ case "required":
366
+ attrs.push("required");
367
+ break;
368
+ case "email":
369
+ attrs.push('type="email"');
370
+ break;
371
+ case "url":
372
+ attrs.push('type="url"');
373
+ break;
374
+ case "numeric":
375
+ case "integer":
376
+ attrs.push('type="number"');
377
+ if (rule.name === "integer")
378
+ attrs.push('step="1"');
379
+ break;
380
+ case "min":
381
+ if (rule.params?.[0])
382
+ attrs.push(`minlength="${rule.params[0]}"`);
383
+ break;
384
+ case "max":
385
+ if (rule.params?.[0])
386
+ attrs.push(`maxlength="${rule.params[0]}"`);
387
+ break;
388
+ case "regex":
389
+ if (rule.params?.[0])
390
+ attrs.push(`pattern="${rule.params[0]}"`);
391
+ break;
392
+ }
393
+ }
394
+ return `<!-- @validate:${field}:${rules} -->${attrs.length > 0 ? `<!-- attrs:${attrs.join(" ")} -->` : ""}`;
395
+ });
396
+ }
397
+ export const enhancedValidationRules = {
398
+ required: {
399
+ name: "required",
400
+ validate: (value) => {
401
+ if (value === null || value === void 0 || value === "")
402
+ return "This field is required";
403
+ if (Array.isArray(value) && value.length === 0)
404
+ return "This field is required";
405
+ return !0;
406
+ },
407
+ toHtml5: () => ["required"],
408
+ message: "This field is required"
409
+ },
410
+ email: {
411
+ name: "email",
412
+ validate: (value) => {
413
+ if (!value)
414
+ return !0;
415
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(String(value)) || "Please enter a valid email address";
416
+ },
417
+ toHtml5: () => ['type="email"'],
418
+ message: "Please enter a valid email address"
419
+ },
420
+ url: {
421
+ name: "url",
422
+ validate: (value) => {
423
+ if (!value)
424
+ return !0;
425
+ try {
426
+ return new URL(String(value)).protocol.startsWith("http") || "Please enter a valid URL";
427
+ } catch {
428
+ return "Please enter a valid URL";
429
+ }
430
+ },
431
+ toHtml5: () => ['type="url"'],
432
+ message: "Please enter a valid URL"
433
+ },
434
+ numeric: {
435
+ name: "numeric",
436
+ validate: (value) => {
437
+ if (!value)
438
+ return !0;
439
+ return !Number.isNaN(Number(value)) || "Please enter a number";
440
+ },
441
+ toHtml5: () => ['type="number"'],
442
+ message: "Please enter a number"
443
+ },
444
+ integer: {
445
+ name: "integer",
446
+ validate: (value) => {
447
+ if (!value)
448
+ return !0;
449
+ const num = Number(value);
450
+ return Number.isInteger(num) || "Please enter a whole number";
451
+ },
452
+ toHtml5: () => ['type="number"', 'step="1"'],
453
+ message: "Please enter a whole number"
454
+ },
455
+ alpha: {
456
+ name: "alpha",
457
+ validate: (value) => {
458
+ if (!value)
459
+ return !0;
460
+ return /^[a-z]+$/i.test(String(value)) || "Please enter only letters";
461
+ },
462
+ toHtml5: () => ['pattern="[a-zA-Z]+"'],
463
+ message: "Please enter only letters"
464
+ },
465
+ alphanumeric: {
466
+ name: "alphanumeric",
467
+ validate: (value) => {
468
+ if (!value)
469
+ return !0;
470
+ return /^[a-z0-9]+$/i.test(String(value)) || "Please enter only letters and numbers";
471
+ },
472
+ toHtml5: () => ['pattern="[a-zA-Z0-9]+"'],
473
+ message: "Please enter only letters and numbers"
474
+ },
475
+ min: {
476
+ name: "min",
477
+ validate: (value, params) => {
478
+ if (!value)
479
+ return !0;
480
+ const min = Number(params[0]);
481
+ if (typeof value === "string")
482
+ return value.length >= min || `Must be at least ${min} characters`;
483
+ if (typeof value === "number")
484
+ return value >= min || `Must be at least ${min}`;
485
+ if (Array.isArray(value))
486
+ return value.length >= min || `Must have at least ${min} items`;
487
+ return !0;
488
+ },
489
+ toHtml5: (params) => [`minlength="${params[0]}"`, `min="${params[0]}"`],
490
+ message: "Must be at least {{param}} characters"
491
+ },
492
+ max: {
493
+ name: "max",
494
+ validate: (value, params) => {
495
+ if (!value)
496
+ return !0;
497
+ const max = Number(params[0]);
498
+ if (typeof value === "string")
499
+ return value.length <= max || `Must be no more than ${max} characters`;
500
+ if (typeof value === "number")
501
+ return value <= max || `Must be no more than ${max}`;
502
+ if (Array.isArray(value))
503
+ return value.length <= max || `Must have no more than ${max} items`;
504
+ return !0;
505
+ },
506
+ toHtml5: (params) => [`maxlength="${params[0]}"`, `max="${params[0]}"`],
507
+ message: "Must be no more than {{param}} characters"
508
+ },
509
+ between: {
510
+ name: "between",
511
+ validate: (value, params) => {
512
+ if (!value)
513
+ return !0;
514
+ const [min, max] = params.map(Number);
515
+ if (typeof value === "string")
516
+ return value.length >= min && value.length <= max || `Must be between ${min} and ${max} characters`;
517
+ if (typeof value === "number")
518
+ return value >= min && value <= max || `Must be between ${min} and ${max}`;
519
+ return !0;
520
+ },
521
+ toHtml5: (params) => [`minlength="${params[0]}"`, `maxlength="${params[1]}"`],
522
+ message: "Must be between {{min}} and {{max}}"
523
+ },
524
+ confirmed: {
525
+ name: "confirmed",
526
+ validate: (value, _params, allValues) => {
527
+ const fieldNames = Object.keys(allValues);
528
+ for (const key of fieldNames)
529
+ if (key.endsWith("_confirmation") && allValues[key] === value)
530
+ return !0;
531
+ return "Confirmation does not match";
532
+ },
533
+ message: "Confirmation does not match"
534
+ },
535
+ in: {
536
+ name: "in",
537
+ validate: (value, params) => {
538
+ if (!value)
539
+ return !0;
540
+ return params.includes(String(value)) || `Must be one of: ${params.join(", ")}`;
541
+ },
542
+ message: "Must be one of: {{values}}"
543
+ },
544
+ notIn: {
545
+ name: "notIn",
546
+ validate: (value, params) => {
547
+ if (!value)
548
+ return !0;
549
+ return !params.includes(String(value)) || `Must not be: ${params.join(", ")}`;
550
+ },
551
+ message: "Must not be: {{values}}"
552
+ },
553
+ regex: {
554
+ name: "regex",
555
+ validate: (value, params) => {
556
+ if (!value)
557
+ return !0;
558
+ try {
559
+ return new RegExp(params[0]).test(String(value)) || "Invalid format";
560
+ } catch {
561
+ return "Invalid format";
562
+ }
563
+ },
564
+ toHtml5: (params) => [`pattern="${params[0]}"`],
565
+ message: "Invalid format"
566
+ },
567
+ date: {
568
+ name: "date",
569
+ validate: (value) => {
570
+ if (!value)
571
+ return !0;
572
+ const date = new Date(String(value));
573
+ return !Number.isNaN(date.getTime()) || "Please enter a valid date";
574
+ },
575
+ toHtml5: () => ['type="date"'],
576
+ message: "Please enter a valid date"
577
+ },
578
+ before: {
579
+ name: "before",
580
+ validate: (value, params) => {
581
+ if (!value)
582
+ return !0;
583
+ const inputDate = new Date(String(value)), beforeDate = new Date(params[0]);
584
+ return inputDate < beforeDate || `Must be before ${params[0]}`;
585
+ },
586
+ toHtml5: (params) => [`max="${params[0]}"`],
587
+ message: "Must be before {{date}}"
588
+ },
589
+ after: {
590
+ name: "after",
591
+ validate: (value, params) => {
592
+ if (!value)
593
+ return !0;
594
+ const inputDate = new Date(String(value)), afterDate = new Date(params[0]);
595
+ return inputDate > afterDate || `Must be after ${params[0]}`;
596
+ },
597
+ toHtml5: (params) => [`min="${params[0]}"`],
598
+ message: "Must be after {{date}}"
599
+ },
600
+ size: {
601
+ name: "size",
602
+ validate: (value, params) => {
603
+ if (!value)
604
+ return !0;
605
+ const size = Number(params[0]);
606
+ if (typeof value === "string")
607
+ return value.length === size || `Must be exactly ${size} characters`;
608
+ if (Array.isArray(value))
609
+ return value.length === size || `Must have exactly ${size} items`;
610
+ return !0;
611
+ },
612
+ message: "Must be exactly {{size}}"
613
+ },
614
+ phone: {
615
+ name: "phone",
616
+ validate: (value) => {
617
+ if (!value)
618
+ return !0;
619
+ return /^\+?\(?\d{1,4}\)?[-\s./\d]*$/.test(String(value)) || "Please enter a valid phone number";
620
+ },
621
+ toHtml5: () => ['type="tel"', 'pattern="\\+?\\(?\\d{1,4}\\)?[-\\s./\\d]*"'],
622
+ message: "Please enter a valid phone number"
623
+ }
624
+ };
625
+ export function registerEnhancedValidationRule(rule) {
626
+ enhancedValidationRules[rule.name] = rule;
627
+ }
628
+ export function validateValueEnhanced(value, rules, allValues = {}) {
629
+ const errors = [], ruleList = rules.split("|").map((r) => r.trim());
630
+ for (const ruleStr of ruleList) {
631
+ const parsed = parseValidationRule(ruleStr), ruleDef = enhancedValidationRules[parsed.name];
632
+ if (!ruleDef) {
633
+ console.warn(`Unknown validation rule: ${parsed.name}`);
634
+ continue;
635
+ }
636
+ const result = ruleDef.validate(value, parsed.params || [], allValues);
637
+ if (result !== !0)
638
+ errors.push(result);
639
+ }
640
+ return { valid: errors.length === 0, errors };
641
+ }
642
+ export function validateFormEnhanced(values, rules) {
643
+ const errors = {};
644
+ let valid = !0;
645
+ for (const [field, fieldRules] of Object.entries(rules)) {
646
+ const result = validateValueEnhanced(values[field], fieldRules, values);
647
+ if (!result.valid) {
648
+ valid = !1;
649
+ errors[field] = result.errors;
650
+ }
651
+ }
652
+ return { valid, errors };
653
+ }
654
+ export function generateValidationScript(formId, rules) {
655
+ const rulesJson = JSON.stringify(rules);
656
+ return `
657
+ <script>
658
+ (function() {
659
+ const form = document.getElementById('${formId}');
660
+ if (!form) return;
661
+
662
+ const rules = ${rulesJson};
663
+ const validators = {
664
+ required: (v) => v !== null && v !== undefined && v !== '' ? true : 'This field is required',
665
+ email: (v) => !v || /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(v) ? true : 'Please enter a valid email',
666
+ url: (v) => { if (!v) return true; try { new URL(v); return true; }
667
+ catch { return 'Please enter a valid URL'; } },
668
+ numeric: (v) => !v || !isNaN(Number(v)) ? true : 'Please enter a number',
669
+ integer: (v) => !v || Number.isInteger(Number(v)) ? true : 'Please enter a whole number',
670
+ min: (v, p) => !v || (typeof v === 'string' ? v.length >= p : v >= p) ? true : 'Too short/small',
671
+ max: (v, p) => !v || (typeof v === 'string' ? v.length <= p : v <= p) ? true : 'Too long/large',
672
+ regex: (v, p) => !v || new RegExp(p).test(v) ? true : 'Invalid format',
673
+ };
674
+
675
+ form.addEventListener('submit', function(e) {
676
+ let valid = true;
677
+ const errors = {};
678
+
679
+ for (const [field, fieldRules] of Object.entries(rules)) {
680
+ const input = form.querySelector('[name="' + field + '"]');
681
+ if (!input) continue;
682
+
683
+ const value = input.value;
684
+ const ruleList = fieldRules.split('|');
685
+
686
+ for (const rule of ruleList) {
687
+ const [name, param] = rule.split(':');
688
+ const validator = validators[name];
689
+ if (validator) {
690
+ const result = validator(value, param);
691
+ if (result !== true) {
692
+ valid = false;
693
+ errors[field] = errors[field] || [];
694
+ errors[field].push(result);
695
+ input.classList.add('is-invalid');
696
+ break;
697
+ }
698
+ }
699
+ }
700
+ }
701
+
702
+ if (!valid) {
703
+ e.preventDefault();
704
+ console.log('Validation errors:', errors);
705
+ }
706
+ });
707
+ })();
708
+ </script>`.trim();
709
+ }