bsmnt 0.4.0 → 0.4.2

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 (536) hide show
  1. package/dist/{helpers/add → application/add-hooks}/index.d.ts +4 -4
  2. package/dist/application/add-hooks/index.d.ts.map +1 -0
  3. package/dist/{helpers/add → application/add-hooks}/index.js +22 -35
  4. package/dist/application/add-hooks/index.js.map +1 -0
  5. package/dist/{utils → application/add-integration}/format-results.d.ts +1 -6
  6. package/dist/application/add-integration/format-results.d.ts.map +1 -0
  7. package/dist/{utils → application/add-integration}/format-results.js +1 -6
  8. package/dist/application/add-integration/format-results.js.map +1 -0
  9. package/dist/{helpers/integrate → application/add-integration}/index.d.ts +2 -1
  10. package/dist/application/add-integration/index.d.ts.map +1 -0
  11. package/dist/{helpers/integrate → application/add-integration}/index.js +46 -41
  12. package/dist/application/add-integration/index.js.map +1 -0
  13. package/dist/application/create-project/build-context.d.ts +9 -0
  14. package/dist/application/create-project/build-context.d.ts.map +1 -0
  15. package/dist/application/create-project/build-context.js +13 -0
  16. package/dist/application/create-project/build-context.js.map +1 -0
  17. package/dist/application/create-project/index.d.ts +44 -0
  18. package/dist/application/create-project/index.d.ts.map +1 -0
  19. package/dist/application/create-project/index.js +70 -0
  20. package/dist/application/create-project/index.js.map +1 -0
  21. package/dist/application/create-project/map-selection-to-registry.d.ts +3 -0
  22. package/dist/application/create-project/map-selection-to-registry.d.ts.map +1 -0
  23. package/dist/application/create-project/map-selection-to-registry.js +30 -0
  24. package/dist/application/create-project/map-selection-to-registry.js.map +1 -0
  25. package/dist/application/create-project/resolve-selection.d.ts +15 -0
  26. package/dist/application/create-project/resolve-selection.d.ts.map +1 -0
  27. package/dist/application/create-project/resolve-selection.js +11 -0
  28. package/dist/application/create-project/resolve-selection.js.map +1 -0
  29. package/dist/{helpers/skills → application/install-skills}/index.d.ts +1 -1
  30. package/dist/application/install-skills/index.d.ts.map +1 -0
  31. package/dist/{helpers/skills → application/install-skills}/index.js +31 -44
  32. package/dist/application/install-skills/index.js.map +1 -0
  33. package/dist/{utils/detect-project.d.ts → application/shared/project-detection.d.ts} +8 -15
  34. package/dist/application/shared/project-detection.d.ts.map +1 -0
  35. package/dist/{utils/detect-project.js → application/shared/project-detection.js} +8 -24
  36. package/dist/application/shared/project-detection.js.map +1 -0
  37. package/dist/core/create/build-plan.d.ts +8 -0
  38. package/dist/core/create/build-plan.d.ts.map +1 -0
  39. package/dist/core/create/build-plan.js +89 -0
  40. package/dist/core/create/build-plan.js.map +1 -0
  41. package/dist/core/create/execute-plan.d.ts +23 -0
  42. package/dist/core/create/execute-plan.d.ts.map +1 -0
  43. package/dist/core/create/execute-plan.js +23 -0
  44. package/dist/core/create/execute-plan.js.map +1 -0
  45. package/dist/core/create/internal-ids.d.ts +23 -0
  46. package/dist/core/create/internal-ids.d.ts.map +1 -0
  47. package/dist/core/create/internal-ids.js +36 -0
  48. package/dist/core/create/internal-ids.js.map +1 -0
  49. package/dist/core/create/registry.d.ts +12 -0
  50. package/dist/core/create/registry.d.ts.map +1 -0
  51. package/dist/core/create/registry.js +33 -0
  52. package/dist/core/create/registry.js.map +1 -0
  53. package/dist/core/create/types.d.ts +96 -0
  54. package/dist/core/create/types.d.ts.map +1 -0
  55. package/dist/core/create/types.js +2 -0
  56. package/dist/core/create/types.js.map +1 -0
  57. package/dist/domain/agents.d.ts +61 -0
  58. package/dist/domain/agents.d.ts.map +1 -0
  59. package/dist/domain/agents.js +35 -0
  60. package/dist/domain/agents.js.map +1 -0
  61. package/dist/domain/animations.d.ts +20 -0
  62. package/dist/domain/animations.d.ts.map +1 -0
  63. package/dist/domain/animations.js +13 -0
  64. package/dist/domain/animations.js.map +1 -0
  65. package/dist/domain/cms.d.ts +24 -0
  66. package/dist/domain/cms.d.ts.map +1 -0
  67. package/dist/domain/cms.js +13 -0
  68. package/dist/domain/cms.js.map +1 -0
  69. package/dist/domain/hooks.d.ts +67 -0
  70. package/dist/domain/hooks.d.ts.map +1 -0
  71. package/dist/domain/hooks.js +52 -0
  72. package/dist/domain/hooks.js.map +1 -0
  73. package/dist/domain/skills.d.ts +70 -0
  74. package/dist/domain/skills.d.ts.map +1 -0
  75. package/dist/domain/skills.js +84 -0
  76. package/dist/domain/skills.js.map +1 -0
  77. package/dist/domain/templates.d.ts +51 -0
  78. package/dist/domain/templates.d.ts.map +1 -0
  79. package/dist/domain/templates.js +27 -0
  80. package/dist/domain/templates.js.map +1 -0
  81. package/dist/index.js +124 -115
  82. package/dist/index.js.map +1 -1
  83. package/dist/infrastructure/agents/register-sanity-mcp.d.ts +12 -0
  84. package/dist/infrastructure/agents/register-sanity-mcp.d.ts.map +1 -0
  85. package/dist/infrastructure/agents/register-sanity-mcp.js +153 -0
  86. package/dist/infrastructure/agents/register-sanity-mcp.js.map +1 -0
  87. package/dist/infrastructure/create/apply-copy-paths.d.ts +3 -0
  88. package/dist/infrastructure/create/apply-copy-paths.d.ts.map +1 -0
  89. package/dist/infrastructure/create/apply-copy-paths.js +12 -0
  90. package/dist/infrastructure/create/apply-copy-paths.js.map +1 -0
  91. package/dist/infrastructure/create/apply-merge-paths.d.ts +3 -0
  92. package/dist/infrastructure/create/apply-merge-paths.d.ts.map +1 -0
  93. package/dist/infrastructure/create/apply-merge-paths.js +17 -0
  94. package/dist/infrastructure/create/apply-merge-paths.js.map +1 -0
  95. package/dist/infrastructure/create/apply-package-json.d.ts +8 -0
  96. package/dist/infrastructure/create/apply-package-json.d.ts.map +1 -0
  97. package/dist/infrastructure/create/apply-package-json.js +46 -0
  98. package/dist/infrastructure/create/apply-package-json.js.map +1 -0
  99. package/dist/infrastructure/create/copy-template.d.ts +10 -0
  100. package/dist/infrastructure/create/copy-template.d.ts.map +1 -0
  101. package/dist/infrastructure/create/copy-template.js.map +1 -0
  102. package/dist/infrastructure/create/executor.d.ts +3 -0
  103. package/dist/infrastructure/create/executor.d.ts.map +1 -0
  104. package/dist/infrastructure/create/executor.js +21 -0
  105. package/dist/infrastructure/create/executor.js.map +1 -0
  106. package/dist/{helpers/create/init-git.d.ts → infrastructure/create/init-git-repo.d.ts} +2 -3
  107. package/dist/infrastructure/create/init-git-repo.d.ts.map +1 -0
  108. package/dist/{helpers/create/init-git.js → infrastructure/create/init-git-repo.js} +1 -4
  109. package/dist/infrastructure/create/init-git-repo.js.map +1 -0
  110. package/dist/{helpers/create/install.d.ts → infrastructure/create/install-dependencies.d.ts} +1 -1
  111. package/dist/infrastructure/create/install-dependencies.d.ts.map +1 -0
  112. package/dist/{helpers/create/install.js → infrastructure/create/install-dependencies.js} +1 -1
  113. package/dist/infrastructure/create/install-dependencies.js.map +1 -0
  114. package/dist/infrastructure/create/lifecycle-registry.d.ts +3 -0
  115. package/dist/infrastructure/create/lifecycle-registry.d.ts.map +1 -0
  116. package/dist/infrastructure/create/lifecycle-registry.js +38 -0
  117. package/dist/infrastructure/create/lifecycle-registry.js.map +1 -0
  118. package/dist/infrastructure/create/merge-registry.d.ts +3 -0
  119. package/dist/infrastructure/create/merge-registry.d.ts.map +1 -0
  120. package/dist/infrastructure/create/merge-registry.js +27 -0
  121. package/dist/infrastructure/create/merge-registry.js.map +1 -0
  122. package/dist/infrastructure/create/rename-files.d.ts.map +1 -0
  123. package/dist/infrastructure/create/rename-files.js.map +1 -0
  124. package/dist/{helpers → infrastructure}/create/setup-agent.d.ts +9 -7
  125. package/dist/infrastructure/create/setup-agent.d.ts.map +1 -0
  126. package/dist/infrastructure/create/setup-agent.js +77 -0
  127. package/dist/infrastructure/create/setup-agent.js.map +1 -0
  128. package/dist/infrastructure/create/setup-sanity.d.ts.map +1 -0
  129. package/dist/{helpers → infrastructure}/create/setup-sanity.js +1 -19
  130. package/dist/infrastructure/create/setup-sanity.js.map +1 -0
  131. package/dist/infrastructure/integrations/inject-integration.d.ts +9 -0
  132. package/dist/infrastructure/integrations/inject-integration.d.ts.map +1 -0
  133. package/dist/{helpers/integrate/merge-orchestrator.js → infrastructure/integrations/inject-integration.js} +26 -38
  134. package/dist/infrastructure/integrations/inject-integration.js.map +1 -0
  135. package/dist/modules/features/agents/index.d.ts +3 -0
  136. package/dist/modules/features/agents/index.d.ts.map +1 -0
  137. package/dist/modules/features/agents/index.js +4 -0
  138. package/dist/modules/features/agents/index.js.map +1 -0
  139. package/dist/modules/features/agents/shared.d.ts +4 -0
  140. package/dist/modules/features/agents/shared.d.ts.map +1 -0
  141. package/dist/modules/features/agents/shared.js +21 -0
  142. package/dist/modules/features/agents/shared.js.map +1 -0
  143. package/dist/{configs/animations.d.ts → modules/features/animation/config.d.ts} +1 -1
  144. package/dist/modules/features/animation/config.d.ts.map +1 -0
  145. package/dist/{configs/animations.js → modules/features/animation/config.js} +1 -1
  146. package/dist/modules/features/animation/config.js.map +1 -0
  147. package/dist/modules/features/animation/gsap.d.ts +3 -0
  148. package/dist/modules/features/animation/gsap.d.ts.map +1 -0
  149. package/dist/modules/features/animation/gsap.js +16 -0
  150. package/dist/modules/features/animation/gsap.js.map +1 -0
  151. package/dist/modules/features/animation/index.d.ts +3 -0
  152. package/dist/modules/features/animation/index.d.ts.map +1 -0
  153. package/dist/modules/features/animation/index.js +4 -0
  154. package/dist/modules/features/animation/index.js.map +1 -0
  155. package/dist/modules/features/animation/motion.d.ts +3 -0
  156. package/dist/modules/features/animation/motion.d.ts.map +1 -0
  157. package/dist/modules/features/animation/motion.js +16 -0
  158. package/dist/modules/features/animation/motion.js.map +1 -0
  159. package/dist/modules/features/cms/index.d.ts +3 -0
  160. package/dist/modules/features/cms/index.d.ts.map +1 -0
  161. package/dist/modules/features/cms/index.js +7 -0
  162. package/dist/modules/features/cms/index.js.map +1 -0
  163. package/dist/modules/features/cms/sanity/config.d.ts.map +1 -0
  164. package/dist/{helpers/integrate → modules/features/cms}/sanity/config.js +3 -2
  165. package/dist/modules/features/cms/sanity/config.js.map +1 -0
  166. package/dist/modules/features/cms/sanity/index.d.ts +3 -0
  167. package/dist/modules/features/cms/sanity/index.d.ts.map +1 -0
  168. package/dist/modules/features/cms/sanity/index.js +61 -0
  169. package/dist/modules/features/cms/sanity/index.js.map +1 -0
  170. package/dist/{helpers/integrate/sanity/mergers/check-integration-merger.d.ts → modules/features/cms/sanity/mergers/check-integration.d.ts} +1 -1
  171. package/dist/modules/features/cms/sanity/mergers/check-integration.d.ts.map +1 -0
  172. package/dist/{helpers/integrate/sanity/mergers/check-integration-merger.js → modules/features/cms/sanity/mergers/check-integration.js} +1 -1
  173. package/dist/modules/features/cms/sanity/mergers/check-integration.js.map +1 -0
  174. package/dist/{helpers/integrate/sanity/mergers/layout-merger.d.ts → modules/features/cms/sanity/mergers/layout.d.ts} +1 -1
  175. package/dist/modules/features/cms/sanity/mergers/layout.d.ts.map +1 -0
  176. package/dist/{helpers/integrate/sanity/mergers/layout-merger.js → modules/features/cms/sanity/mergers/layout.js} +1 -1
  177. package/dist/modules/features/cms/sanity/mergers/layout.js.map +1 -0
  178. package/dist/modules/features/cms/sanity/mergers/sitemap.d.ts +13 -0
  179. package/dist/modules/features/cms/sanity/mergers/sitemap.d.ts.map +1 -0
  180. package/dist/modules/features/cms/sanity/mergers/sitemap.js +92 -0
  181. package/dist/modules/features/cms/sanity/mergers/sitemap.js.map +1 -0
  182. package/dist/modules/features/cms/sanity-pagebuilder/config.d.ts +14 -0
  183. package/dist/modules/features/cms/sanity-pagebuilder/config.d.ts.map +1 -0
  184. package/dist/modules/features/cms/sanity-pagebuilder/config.js +44 -0
  185. package/dist/modules/features/cms/sanity-pagebuilder/config.js.map +1 -0
  186. package/dist/modules/features/cms/sanity-pagebuilder/index.d.ts +3 -0
  187. package/dist/modules/features/cms/sanity-pagebuilder/index.d.ts.map +1 -0
  188. package/dist/modules/features/cms/sanity-pagebuilder/index.js +46 -0
  189. package/dist/modules/features/cms/sanity-pagebuilder/index.js.map +1 -0
  190. package/dist/modules/features/hooks/factory.d.ts +4 -0
  191. package/dist/modules/features/hooks/factory.d.ts.map +1 -0
  192. package/dist/modules/features/hooks/factory.js +26 -0
  193. package/dist/modules/features/hooks/factory.js.map +1 -0
  194. package/dist/modules/features/hooks/index.d.ts +3 -0
  195. package/dist/modules/features/hooks/index.d.ts.map +1 -0
  196. package/dist/modules/features/hooks/index.js +4 -0
  197. package/dist/modules/features/hooks/index.js.map +1 -0
  198. package/dist/modules/presets/index.d.ts +3 -0
  199. package/dist/modules/presets/index.d.ts.map +1 -0
  200. package/dist/modules/presets/index.js +11 -0
  201. package/dist/modules/presets/index.js.map +1 -0
  202. package/dist/modules/presets/next-default.d.ts +3 -0
  203. package/dist/modules/presets/next-default.d.ts.map +1 -0
  204. package/dist/modules/presets/next-default.js +9 -0
  205. package/dist/modules/presets/next-default.js.map +1 -0
  206. package/dist/modules/presets/next-experiments.d.ts +3 -0
  207. package/dist/modules/presets/next-experiments.d.ts.map +1 -0
  208. package/dist/modules/presets/next-experiments.js +9 -0
  209. package/dist/modules/presets/next-experiments.js.map +1 -0
  210. package/dist/modules/presets/next-pagebuilder.d.ts +3 -0
  211. package/dist/modules/presets/next-pagebuilder.d.ts.map +1 -0
  212. package/dist/modules/presets/next-pagebuilder.js +10 -0
  213. package/dist/modules/presets/next-pagebuilder.js.map +1 -0
  214. package/dist/modules/presets/next-webgl.d.ts +3 -0
  215. package/dist/modules/presets/next-webgl.d.ts.map +1 -0
  216. package/dist/modules/presets/next-webgl.js +9 -0
  217. package/dist/modules/presets/next-webgl.js.map +1 -0
  218. package/dist/paths.d.ts +7 -1
  219. package/dist/paths.d.ts.map +1 -1
  220. package/dist/paths.js +8 -2
  221. package/dist/paths.js.map +1 -1
  222. package/index.js +2 -2
  223. package/package.json +11 -4
  224. package/src/modules/features/cms/sanity/files/.knip.json +8 -0
  225. package/src/{helpers/integrate → modules/features/cms}/sanity/files/app/api/blog/[slug]/route.ts +3 -4
  226. package/src/{helpers/integrate → modules/features/cms}/sanity/files/app/api/revalidate/route.ts +1 -4
  227. package/src/{helpers/integrate → modules/features/cms}/sanity/files/app/blog/[slug]/page.tsx +8 -9
  228. package/src/{helpers/integrate → modules/features/cms}/sanity/files/app/layout.tsx +2 -2
  229. package/src/{helpers/integrate → modules/features/cms}/sanity/files/app/sitemap.md/route.ts +18 -29
  230. package/src/modules/features/cms/sanity/files/app/sitemap.xml/route.ts +51 -0
  231. package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/env.ts +2 -4
  232. package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/queries.ts +0 -42
  233. package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/schemas/index.ts +1 -1
  234. package/src/modules/features/cms/sanity/files/lib/scripts/copy-sanity-mcp.ts +23 -0
  235. package/src/modules/features/cms/sanity/files/lib/scripts/generate-page.ts +297 -0
  236. package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/utils/json-ld.tsx +1 -6
  237. package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/utils/metadata.ts +2 -2
  238. package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/utils/url.ts +4 -2
  239. package/src/{helpers/integrate → modules/features/cms}/sanity/files/proxy.ts +11 -11
  240. package/src/template-hooks/use-device-perf.ts +27 -17
  241. package/src/templates/next-default/.env.example +3 -3
  242. package/src/templates/next-default/.vscode/extensions.json +1 -5
  243. package/src/templates/next-default/.vscode/settings.json +1 -1
  244. package/src/templates/next-default/.zed/settings.json +47 -0
  245. package/src/templates/next-default/README.md +7 -6
  246. package/src/templates/next-default/_gitignore +1 -3
  247. package/src/templates/next-default/app/layout.tsx +21 -35
  248. package/src/templates/next-default/app/robots.ts +3 -4
  249. package/src/templates/next-default/app/sitemap.xml/route.ts +29 -29
  250. package/src/templates/next-default/biome.json +9 -2
  251. package/src/templates/next-default/components/ui/image/index.tsx +2 -1
  252. package/src/templates/next-default/components/ui/link/index.tsx +35 -35
  253. package/src/templates/next-default/lefthook.yml +25 -0
  254. package/src/templates/next-default/lib/README.md +8 -4
  255. package/src/templates/next-default/lib/hooks/use-media.ts +6 -3
  256. package/src/templates/next-default/lib/scripts/dev.ts +32 -0
  257. package/src/templates/next-default/lib/styles/README.md +13 -0
  258. package/src/templates/next-default/lib/styles/fonts.ts +20 -0
  259. package/src/templates/next-default/lib/styles/global.css +15 -196
  260. package/src/templates/next-default/lib/styles/index.css +3 -0
  261. package/src/templates/next-default/lib/styles/tokens.css +182 -0
  262. package/src/templates/next-default/lib/utils/README.md +40 -0
  263. package/src/templates/next-default/lib/utils/easings.ts +240 -0
  264. package/src/templates/next-default/lib/utils/fetch.ts +84 -0
  265. package/src/templates/next-default/lib/utils/global-css.d.ts +1 -0
  266. package/src/templates/next-default/lib/utils/json-ld.tsx +70 -68
  267. package/src/templates/next-default/lib/utils/math.ts +236 -0
  268. package/src/templates/next-default/lib/utils/metadata.ts +26 -27
  269. package/src/templates/next-default/lib/utils/strings.ts +246 -0
  270. package/src/templates/next-default/lib/utils/types.d.ts +15 -0
  271. package/src/templates/next-default/lib/utils/url.ts +8 -5
  272. package/src/templates/next-default/lib/utils/viewport.ts +199 -0
  273. package/src/templates/next-default/package.json +12 -7
  274. package/src/templates/next-default/svg.d.ts +1 -0
  275. package/src/templates/next-experiments/.env.example +3 -3
  276. package/src/templates/next-experiments/.knip.json +3 -0
  277. package/src/templates/next-experiments/.vscode/extensions.json +1 -5
  278. package/src/templates/next-experiments/.vscode/settings.json +1 -1
  279. package/src/templates/next-experiments/.zed/settings.json +47 -0
  280. package/src/templates/next-experiments/README.md +7 -6
  281. package/src/templates/next-experiments/_gitignore +1 -3
  282. package/src/templates/next-experiments/app/layout.tsx +21 -35
  283. package/src/templates/next-experiments/app/robots.ts +5 -2
  284. package/src/templates/next-experiments/app/sitemap.xml/route.ts +51 -0
  285. package/src/templates/next-experiments/biome.json +4 -2
  286. package/src/templates/next-experiments/components/layout/navigation-menu.tsx +1 -1
  287. package/src/templates/next-experiments/components/layout/wrapper/index.tsx +6 -6
  288. package/src/templates/next-experiments/components/ui/image/index.tsx +33 -33
  289. package/src/templates/next-experiments/lib/README.md +8 -4
  290. package/src/templates/next-experiments/lib/hooks/use-media.ts +6 -3
  291. package/src/templates/next-experiments/lib/scripts/dev.ts +32 -0
  292. package/src/templates/next-experiments/lib/styles/README.md +13 -0
  293. package/src/templates/next-experiments/lib/styles/fonts.ts +20 -0
  294. package/src/templates/next-experiments/lib/styles/global.css +16 -196
  295. package/src/templates/next-experiments/lib/styles/index.css +3 -0
  296. package/src/templates/next-experiments/lib/styles/tokens.css +182 -0
  297. package/src/templates/next-experiments/lib/utils/README.md +40 -0
  298. package/src/templates/next-experiments/lib/utils/easings.ts +240 -0
  299. package/src/templates/next-experiments/lib/utils/fetch.ts +84 -0
  300. package/src/templates/next-experiments/lib/utils/global-css.d.ts +1 -0
  301. package/src/templates/next-experiments/lib/utils/json-ld.tsx +70 -68
  302. package/src/templates/next-experiments/lib/utils/math.ts +236 -0
  303. package/src/templates/next-experiments/lib/utils/metadata.ts +26 -27
  304. package/src/templates/next-experiments/lib/utils/strings.ts +246 -0
  305. package/src/templates/next-experiments/lib/utils/types.d.ts +15 -0
  306. package/src/templates/next-experiments/lib/utils/url.ts +8 -5
  307. package/src/templates/next-experiments/lib/utils/viewport.ts +199 -0
  308. package/src/templates/next-experiments/package.json +6 -6
  309. package/src/templates/next-experiments/svg.d.ts +1 -0
  310. package/src/templates/next-pagebuilder/.vscode/extensions.json +16 -0
  311. package/src/templates/next-pagebuilder/.vscode/settings.json +105 -0
  312. package/src/templates/next-pagebuilder/.zed/settings.json +47 -0
  313. package/src/templates/next-pagebuilder/_gitignore +1 -3
  314. package/src/templates/next-pagebuilder/app/(content)/[[...slug]]/page.tsx +17 -8
  315. package/src/templates/next-pagebuilder/app/(content)/layout.tsx +18 -7
  316. package/src/templates/next-pagebuilder/app/actions/refresh.ts +5 -0
  317. package/src/templates/next-pagebuilder/app/robots.ts +3 -4
  318. package/src/templates/next-pagebuilder/biome.json +17 -0
  319. package/src/templates/next-pagebuilder/components/layout/footer/index.tsx +17 -22
  320. package/src/templates/next-pagebuilder/components/layout/header/index.tsx +3 -5
  321. package/src/templates/next-pagebuilder/components/layout/json-ld/index.tsx +11 -10
  322. package/src/templates/next-pagebuilder/components/layout/wrapper/index.tsx +14 -4
  323. package/src/templates/next-pagebuilder/components/page-builder/components/article-content/index.tsx +4 -9
  324. package/src/templates/next-pagebuilder/components/page-builder/components/article-content/related-post-item.tsx +4 -4
  325. package/src/templates/next-pagebuilder/components/page-builder/components/{post-collection → content-collection}/content-card.tsx +2 -2
  326. package/src/templates/next-pagebuilder/components/page-builder/components/content-collection/content-filters.tsx +93 -0
  327. package/src/templates/next-pagebuilder/components/page-builder/components/{post-collection → content-collection}/content-grid.tsx +7 -9
  328. package/src/templates/next-pagebuilder/components/page-builder/components/content-collection/content-pagination-nav.tsx +71 -0
  329. package/src/templates/next-pagebuilder/components/page-builder/components/content-collection/index.tsx +219 -0
  330. package/src/templates/next-pagebuilder/components/page-builder/components/{post-collection → content-collection}/types.ts +7 -4
  331. package/src/templates/next-pagebuilder/components/page-builder/renderer.tsx +17 -5
  332. package/src/templates/next-pagebuilder/components/page-builder/types.ts +9 -7
  333. package/src/templates/next-pagebuilder/components/page-document/index.tsx +19 -4
  334. package/src/templates/next-pagebuilder/lefthook.yml +25 -0
  335. package/src/templates/next-pagebuilder/lib/integrations/sanity/sanity.types.ts +208 -0
  336. package/src/templates/next-pagebuilder/lib/styles/global.css +0 -1
  337. package/src/templates/next-pagebuilder/next.config.ts +1 -0
  338. package/src/templates/next-pagebuilder/package.json +13 -26
  339. package/src/templates/next-pagebuilder/postcss.config.mjs +27 -1
  340. package/src/templates/next-pagebuilder/svg.d.ts +1 -0
  341. package/src/templates/next-webgl/.env.example +3 -3
  342. package/src/templates/next-webgl/.vscode/extensions.json +1 -5
  343. package/src/templates/next-webgl/.vscode/settings.json +1 -1
  344. package/src/templates/next-webgl/.zed/settings.json +47 -0
  345. package/src/templates/next-webgl/README.md +7 -6
  346. package/src/templates/next-webgl/_gitignore +1 -3
  347. package/src/templates/next-webgl/app/layout.tsx +21 -35
  348. package/src/templates/next-webgl/app/robots.ts +3 -4
  349. package/src/templates/next-webgl/app/sitemap.xml/route.ts +29 -29
  350. package/src/templates/next-webgl/biome.json +9 -2
  351. package/src/templates/next-webgl/components/ui/image/index.tsx +2 -1
  352. package/src/templates/next-webgl/components/webgl/components/scene/index.tsx +0 -2
  353. package/src/templates/next-webgl/lefthook.yml +25 -0
  354. package/src/templates/next-webgl/lib/README.md +8 -4
  355. package/src/templates/next-webgl/lib/hooks/use-media.ts +6 -3
  356. package/src/templates/next-webgl/lib/scripts/dev.ts +32 -0
  357. package/src/templates/next-webgl/lib/styles/README.md +13 -0
  358. package/src/templates/next-webgl/lib/styles/fonts.ts +20 -0
  359. package/src/templates/next-webgl/lib/styles/global.css +16 -196
  360. package/src/templates/next-webgl/lib/styles/index.css +3 -0
  361. package/src/templates/next-webgl/lib/styles/tokens.css +182 -0
  362. package/src/templates/next-webgl/lib/utils/README.md +40 -0
  363. package/src/templates/next-webgl/lib/utils/easings.ts +240 -0
  364. package/src/templates/next-webgl/lib/utils/fetch.ts +84 -0
  365. package/src/templates/next-webgl/lib/utils/global-css.d.ts +1 -0
  366. package/src/templates/next-webgl/lib/utils/json-ld.tsx +70 -68
  367. package/src/templates/next-webgl/lib/utils/math.ts +236 -0
  368. package/src/templates/next-webgl/lib/utils/metadata.ts +26 -27
  369. package/src/templates/next-webgl/lib/utils/strings.ts +246 -0
  370. package/src/templates/next-webgl/lib/utils/types.d.ts +15 -0
  371. package/src/templates/next-webgl/lib/utils/url.ts +8 -5
  372. package/src/templates/next-webgl/lib/utils/viewport.ts +199 -0
  373. package/src/templates/next-webgl/package.json +13 -8
  374. package/src/templates/next-webgl/svg.d.ts +1 -0
  375. package/src/templates/next-webgl/tsconfig.tsbuildinfo +1 -1
  376. package/dist/configs/animations.d.ts.map +0 -1
  377. package/dist/configs/animations.js.map +0 -1
  378. package/dist/configs/skills.d.ts +0 -27
  379. package/dist/configs/skills.d.ts.map +0 -1
  380. package/dist/configs/skills.js +0 -18
  381. package/dist/configs/skills.js.map +0 -1
  382. package/dist/configs/skills.json +0 -26
  383. package/dist/helpers/add/hooks-config.d.ts +0 -22
  384. package/dist/helpers/add/hooks-config.d.ts.map +0 -1
  385. package/dist/helpers/add/hooks-config.js +0 -31
  386. package/dist/helpers/add/hooks-config.js.map +0 -1
  387. package/dist/helpers/add/index.d.ts.map +0 -1
  388. package/dist/helpers/add/index.js.map +0 -1
  389. package/dist/helpers/create/copy-template.d.ts +0 -11
  390. package/dist/helpers/create/copy-template.d.ts.map +0 -1
  391. package/dist/helpers/create/copy-template.js.map +0 -1
  392. package/dist/helpers/create/index.d.ts +0 -24
  393. package/dist/helpers/create/index.d.ts.map +0 -1
  394. package/dist/helpers/create/index.js +0 -99
  395. package/dist/helpers/create/index.js.map +0 -1
  396. package/dist/helpers/create/init-git.d.ts.map +0 -1
  397. package/dist/helpers/create/init-git.js.map +0 -1
  398. package/dist/helpers/create/install.d.ts.map +0 -1
  399. package/dist/helpers/create/install.js.map +0 -1
  400. package/dist/helpers/create/rename-files.d.ts.map +0 -1
  401. package/dist/helpers/create/rename-files.js.map +0 -1
  402. package/dist/helpers/create/setup-agent.d.ts.map +0 -1
  403. package/dist/helpers/create/setup-agent.js +0 -91
  404. package/dist/helpers/create/setup-agent.js.map +0 -1
  405. package/dist/helpers/create/setup-sanity.d.ts.map +0 -1
  406. package/dist/helpers/create/setup-sanity.js.map +0 -1
  407. package/dist/helpers/create/update-package.d.ts +0 -20
  408. package/dist/helpers/create/update-package.d.ts.map +0 -1
  409. package/dist/helpers/create/update-package.js +0 -97
  410. package/dist/helpers/create/update-package.js.map +0 -1
  411. package/dist/helpers/integrate/index.d.ts.map +0 -1
  412. package/dist/helpers/integrate/index.js.map +0 -1
  413. package/dist/helpers/integrate/merge-config.d.ts +0 -21
  414. package/dist/helpers/integrate/merge-config.d.ts.map +0 -1
  415. package/dist/helpers/integrate/merge-config.js +0 -42
  416. package/dist/helpers/integrate/merge-config.js.map +0 -1
  417. package/dist/helpers/integrate/merge-orchestrator.d.ts +0 -10
  418. package/dist/helpers/integrate/merge-orchestrator.d.ts.map +0 -1
  419. package/dist/helpers/integrate/merge-orchestrator.js.map +0 -1
  420. package/dist/helpers/integrate/sanity/config.d.ts.map +0 -1
  421. package/dist/helpers/integrate/sanity/config.js.map +0 -1
  422. package/dist/helpers/integrate/sanity/mergers/check-integration-merger.d.ts.map +0 -1
  423. package/dist/helpers/integrate/sanity/mergers/check-integration-merger.js.map +0 -1
  424. package/dist/helpers/integrate/sanity/mergers/layout-merger.d.ts.map +0 -1
  425. package/dist/helpers/integrate/sanity/mergers/layout-merger.js.map +0 -1
  426. package/dist/helpers/integrate/sanity/mergers/sitemap-merger.d.ts +0 -11
  427. package/dist/helpers/integrate/sanity/mergers/sitemap-merger.d.ts.map +0 -1
  428. package/dist/helpers/integrate/sanity/mergers/sitemap-merger.js +0 -133
  429. package/dist/helpers/integrate/sanity/mergers/sitemap-merger.js.map +0 -1
  430. package/dist/helpers/skills/index.d.ts.map +0 -1
  431. package/dist/helpers/skills/index.js.map +0 -1
  432. package/dist/utils/detect-project.d.ts.map +0 -1
  433. package/dist/utils/detect-project.js.map +0 -1
  434. package/dist/utils/format-results.d.ts.map +0 -1
  435. package/dist/utils/format-results.js.map +0 -1
  436. package/src/helpers/integrate/sanity/files/lib/integrations/sanity/WEBHOOK-SETUP.md +0 -74
  437. package/src/helpers/integrate/sanity/files/lib/integrations/sanity/sitemap.ts +0 -90
  438. package/src/template-hooks/config.js +0 -32
  439. package/src/templates/next-default/css.d.ts +0 -1
  440. package/src/templates/next-default/lib/utils/portable-text-to-markdown.ts +0 -83
  441. package/src/templates/next-default/tsconfig.tsbuildinfo +0 -1
  442. package/src/templates/next-experiments/css.d.ts +0 -1
  443. package/src/templates/next-experiments/lib/utils/portable-text-to-markdown.ts +0 -83
  444. package/src/templates/next-pagebuilder/app/api/[[...slug]]/route.ts +0 -100
  445. package/src/templates/next-pagebuilder/app/api/draft-mode/disable/route.ts +0 -7
  446. package/src/templates/next-pagebuilder/app/api/draft-mode/enable/route.ts +0 -20
  447. package/src/templates/next-pagebuilder/app/api/revalidate/route.ts +0 -121
  448. package/src/templates/next-pagebuilder/app/sitemap.md/route.ts +0 -124
  449. package/src/templates/next-pagebuilder/app/studio/[[...tool]]/page.tsx +0 -8
  450. package/src/templates/next-pagebuilder/components/page-builder/components/post-collection/index.tsx +0 -28
  451. package/src/templates/next-pagebuilder/components/sanity/draft-mode-toggle.tsx +0 -27
  452. package/src/templates/next-pagebuilder/components/sanity/rich-text.tsx +0 -87
  453. package/src/templates/next-pagebuilder/components/sanity/visual-editing.tsx +0 -27
  454. package/src/templates/next-pagebuilder/components/ui/sanity-image/index.tsx +0 -41
  455. package/src/templates/next-pagebuilder/lib/integrations/check-integration.ts +0 -5
  456. package/src/templates/next-pagebuilder/lib/integrations/sanity/client.ts +0 -27
  457. package/src/templates/next-pagebuilder/lib/integrations/sanity/components/disable-draft-mode.tsx +0 -23
  458. package/src/templates/next-pagebuilder/lib/integrations/sanity/components/page-builder-input.tsx +0 -36
  459. package/src/templates/next-pagebuilder/lib/integrations/sanity/components/page-category-input.tsx +0 -50
  460. package/src/templates/next-pagebuilder/lib/integrations/sanity/components/rich-text.tsx +0 -84
  461. package/src/templates/next-pagebuilder/lib/integrations/sanity/confirm-publish-action.ts +0 -40
  462. package/src/templates/next-pagebuilder/lib/integrations/sanity/env.ts +0 -34
  463. package/src/templates/next-pagebuilder/lib/integrations/sanity/fetchers/layout.ts +0 -35
  464. package/src/templates/next-pagebuilder/lib/integrations/sanity/icons.ts +0 -58
  465. package/src/templates/next-pagebuilder/lib/integrations/sanity/live/index.tsx +0 -61
  466. package/src/templates/next-pagebuilder/lib/integrations/sanity/markdown-proxy.config.ts +0 -50
  467. package/src/templates/next-pagebuilder/lib/integrations/sanity/page-builder-config.ts +0 -132
  468. package/src/templates/next-pagebuilder/lib/integrations/sanity/page-category.ts +0 -28
  469. package/src/templates/next-pagebuilder/lib/integrations/sanity/queries.ts +0 -281
  470. package/src/templates/next-pagebuilder/lib/integrations/sanity/sanity.cli.ts +0 -29
  471. package/src/templates/next-pagebuilder/lib/integrations/sanity/sanity.config.ts +0 -211
  472. package/src/templates/next-pagebuilder/lib/integrations/sanity/schemas/components/index.ts +0 -4
  473. package/src/templates/next-pagebuilder/lib/integrations/sanity/schemas/components/reusable/blog-content.ts +0 -89
  474. package/src/templates/next-pagebuilder/lib/integrations/sanity/schemas/components/reusable/description.ts +0 -29
  475. package/src/templates/next-pagebuilder/lib/integrations/sanity/schemas/components/reusable/hero.ts +0 -28
  476. package/src/templates/next-pagebuilder/lib/integrations/sanity/schemas/components/singleton/content-collection.ts +0 -45
  477. package/src/templates/next-pagebuilder/lib/integrations/sanity/schemas/content/author.ts +0 -70
  478. package/src/templates/next-pagebuilder/lib/integrations/sanity/schemas/content/blog-category.ts +0 -55
  479. package/src/templates/next-pagebuilder/lib/integrations/sanity/schemas/index.ts +0 -96
  480. package/src/templates/next-pagebuilder/lib/integrations/sanity/schemas/layout/company-data.ts +0 -62
  481. package/src/templates/next-pagebuilder/lib/integrations/sanity/schemas/layout/footer.ts +0 -79
  482. package/src/templates/next-pagebuilder/lib/integrations/sanity/schemas/layout/navbar.ts +0 -74
  483. package/src/templates/next-pagebuilder/lib/integrations/sanity/schemas/shared/link.ts +0 -125
  484. package/src/templates/next-pagebuilder/lib/integrations/sanity/schemas/shared/logo-field.ts +0 -9
  485. package/src/templates/next-pagebuilder/lib/integrations/sanity/schemas/shared/metadata.ts +0 -68
  486. package/src/templates/next-pagebuilder/lib/integrations/sanity/schemas/shared/nav-objects.ts +0 -192
  487. package/src/templates/next-pagebuilder/lib/integrations/sanity/schemas/shared/page-builder.ts +0 -39
  488. package/src/templates/next-pagebuilder/lib/integrations/sanity/schemas/shared/page-folder.ts +0 -124
  489. package/src/templates/next-pagebuilder/lib/integrations/sanity/schemas/shared/page.ts +0 -232
  490. package/src/templates/next-pagebuilder/lib/integrations/sanity/schemas/shared/richText.ts +0 -63
  491. package/src/templates/next-pagebuilder/lib/integrations/sanity/singletons.ts +0 -44
  492. package/src/templates/next-pagebuilder/lib/integrations/sanity/structure.ts +0 -453
  493. package/src/templates/next-pagebuilder/lib/integrations/sanity/utils/image.ts +0 -8
  494. package/src/templates/next-pagebuilder/lib/integrations/sanity/utils/link.ts +0 -137
  495. package/src/templates/next-pagebuilder/lib/integrations/sanity/utils/page-builder-markdown.ts +0 -81
  496. package/src/templates/next-pagebuilder/lib/scripts/sanity-typegen.ts +0 -45
  497. package/src/templates/next-pagebuilder/lib/utils/json-ld.tsx +0 -213
  498. package/src/templates/next-pagebuilder/lib/utils/metadata.ts +0 -167
  499. package/src/templates/next-pagebuilder/lib/utils/sitemap.ts +0 -37
  500. package/src/templates/next-pagebuilder/proxy.ts +0 -81
  501. package/src/templates/next-webgl/css.d.ts +0 -1
  502. package/src/templates/next-webgl/lib/utils/portable-text-to-markdown.ts +0 -83
  503. package/dist/{helpers → infrastructure}/create/copy-template.js +0 -0
  504. package/dist/{helpers → infrastructure}/create/rename-files.d.ts +0 -0
  505. package/dist/{helpers → infrastructure}/create/rename-files.js +0 -0
  506. package/dist/{helpers → infrastructure}/create/setup-sanity.d.ts +0 -0
  507. package/dist/{helpers/integrate → modules/features/cms}/sanity/config.d.ts +0 -0
  508. package/src/{helpers/integrate → modules/features/cms}/sanity/files/app/api/draft-mode/disable/route.ts +0 -0
  509. package/src/{helpers/integrate → modules/features/cms}/sanity/files/app/api/draft-mode/enable/route.ts +0 -0
  510. package/src/{helpers/integrate → modules/features/cms}/sanity/files/app/studio/[[...tool]]/page.tsx +0 -0
  511. package/src/{helpers/integrate → modules/features/cms}/sanity/files/app/studio/layout.tsx +0 -0
  512. package/src/{helpers/integrate → modules/features/cms}/sanity/files/components/ui/sanity-image/index.tsx +0 -0
  513. package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/README.md +0 -0
  514. package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/check-integration.ts +0 -0
  515. package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/MARKDOWN-PROXY.md +0 -0
  516. package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/README.md +0 -0
  517. package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/client.ts +0 -0
  518. package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/components/disable-draft-mode.tsx +0 -0
  519. package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/components/rich-text.tsx +0 -0
  520. package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/confirm-publish-action.ts +0 -0
  521. package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/live/index.tsx +1 -1
  522. package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/markdown-proxy.config.ts +0 -0
  523. package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/sanity.cli.ts +0 -0
  524. package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/sanity.config.ts +1 -1
  525. /package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/sanity.types.ts +0 -0
  526. /package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/schema.json +0 -0
  527. /package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/schemas/article.ts +0 -0
  528. /package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/schemas/example.ts +0 -0
  529. /package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/schemas/link.ts +0 -0
  530. /package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/schemas/metadata.ts +0 -0
  531. /package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/schemas/navigation.ts +0 -0
  532. /package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/schemas/richText.ts +0 -0
  533. /package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/structure.ts +0 -0
  534. /package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/utils/image.ts +0 -0
  535. /package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/integrations/sanity/utils/link.ts +0 -0
  536. /package/src/{helpers/integrate → modules/features/cms}/sanity/files/lib/utils/portable-text-to-markdown.ts +0 -0
@@ -0,0 +1,236 @@
1
+ /**
2
+ * Math Utilities
3
+ *
4
+ * Pure mathematical functions with no side effects.
5
+ * These are the building blocks for animations, layouts, and data transformations.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import { clamp, lerp, mapRange } from '@/utils/math'
10
+ *
11
+ * // Constrain a value
12
+ * const bounded = clamp(0, value, 100)
13
+ *
14
+ * // Interpolate between values
15
+ * const mid = lerp(0, 100, 0.5) // 50
16
+ *
17
+ * // Map scroll position to opacity
18
+ * const opacity = mapRange(0, 500, scrollY, 0, 1, true)
19
+ * ```
20
+ */
21
+
22
+ /**
23
+ * Constrains a value between a minimum and maximum.
24
+ *
25
+ * @param min - Lower bound
26
+ * @param input - Value to constrain
27
+ * @param max - Upper bound
28
+ * @returns The clamped value
29
+ *
30
+ * @example
31
+ * ```ts
32
+ * clamp(0, -5, 100) // 0
33
+ * clamp(0, 50, 100) // 50
34
+ * clamp(0, 150, 100) // 100
35
+ * ```
36
+ */
37
+ export function clamp(min: number, input: number, max: number): number {
38
+ return Math.max(min, Math.min(input, max))
39
+ }
40
+
41
+ /**
42
+ * Linear interpolation between two values.
43
+ *
44
+ * @param start - Starting value
45
+ * @param end - Ending value
46
+ * @param amount - Interpolation factor (0 = start, 1 = end)
47
+ * @returns The interpolated value
48
+ *
49
+ * @example
50
+ * ```ts
51
+ * lerp(0, 100, 0) // 0
52
+ * lerp(0, 100, 0.5) // 50
53
+ * lerp(0, 100, 1) // 100
54
+ * lerp(0, 100, 0.25) // 25
55
+ * ```
56
+ */
57
+ export function lerp(start: number, end: number, amount: number): number {
58
+ return (1 - amount) * start + amount * end
59
+ }
60
+
61
+ /**
62
+ * Maps a value from one range to another.
63
+ *
64
+ * @param inMin - Input range minimum
65
+ * @param inMax - Input range maximum
66
+ * @param input - Value to map
67
+ * @param outMin - Output range minimum
68
+ * @param outMax - Output range maximum
69
+ * @param shouldClamp - Whether to clamp output to range (default: false)
70
+ * @returns The mapped value
71
+ *
72
+ * @example
73
+ * ```ts
74
+ * // Map scroll (0-1000) to opacity (0-1)
75
+ * mapRange(0, 1000, 500, 0, 1) // 0.5
76
+ *
77
+ * // Map with clamping (won't exceed bounds)
78
+ * mapRange(0, 100, 150, 0, 1, true) // 1
79
+ *
80
+ * // Inverted ranges work too
81
+ * mapRange(0, 100, 50, 1, 0) // 0.5
82
+ * ```
83
+ */
84
+ export function mapRange(
85
+ inMin: number,
86
+ inMax: number,
87
+ input: number,
88
+ outMin: number,
89
+ outMax: number,
90
+ shouldClamp = false
91
+ ): number {
92
+ const result =
93
+ ((input - inMin) * (outMax - outMin)) / (inMax - inMin) + outMin
94
+
95
+ if (!shouldClamp) return result
96
+
97
+ const isInverted = outMin > outMax
98
+ return isInverted
99
+ ? clamp(outMax, result, outMin)
100
+ : clamp(outMin, result, outMax)
101
+ }
102
+
103
+ /**
104
+ * Truncates a number to a specified number of decimal places.
105
+ *
106
+ * @param value - Number to truncate
107
+ * @param decimals - Number of decimal places
108
+ * @returns The truncated number
109
+ *
110
+ * @example
111
+ * ```ts
112
+ * truncate(3.14159, 2) // 3.14
113
+ * truncate(3.14159, 0) // 3
114
+ * ```
115
+ */
116
+ export function truncate(value: number, decimals: number): number {
117
+ return Number.parseFloat(value.toFixed(decimals))
118
+ }
119
+
120
+ /**
121
+ * True modulo operation (handles negative numbers correctly).
122
+ *
123
+ * JavaScript's % operator is remainder, not modulo.
124
+ * This function returns a value in [0, d) for positive divisors.
125
+ *
126
+ * @param n - Dividend
127
+ * @param d - Divisor (must be positive)
128
+ * @returns The modulo result
129
+ *
130
+ * @example
131
+ * ```ts
132
+ * // JavaScript remainder vs true modulo
133
+ * -1 % 3 // -1 (remainder)
134
+ * modulo(-1, 3) // 2 (modulo)
135
+ *
136
+ * // Useful for wrapping array indices
137
+ * modulo(index - 1, array.length)
138
+ * ```
139
+ */
140
+ export function modulo(n: number, d: number): number {
141
+ if (d === 0) return n
142
+ if (d < 0) return Number.NaN
143
+ return ((n % d) + d) % d
144
+ }
145
+
146
+ /**
147
+ * Rounds a number to the nearest multiple.
148
+ *
149
+ * @param value - Number to round
150
+ * @param multiple - Multiple to round to
151
+ * @returns The rounded value
152
+ *
153
+ * @example
154
+ * ```ts
155
+ * roundTo(23, 10) // 20
156
+ * roundTo(27, 10) // 30
157
+ * roundTo(0.23, 0.1) // 0.2
158
+ * ```
159
+ */
160
+ export function roundTo(value: number, multiple: number): number {
161
+ return Math.round(value / multiple) * multiple
162
+ }
163
+
164
+ /**
165
+ * Converts degrees to radians.
166
+ *
167
+ * @param degrees - Angle in degrees
168
+ * @returns Angle in radians
169
+ *
170
+ * @example
171
+ * ```ts
172
+ * degToRad(180) // Math.PI
173
+ * degToRad(90) // Math.PI / 2
174
+ * ```
175
+ */
176
+ export function degToRad(degrees: number): number {
177
+ return (degrees * Math.PI) / 180
178
+ }
179
+
180
+ /**
181
+ * Converts radians to degrees.
182
+ *
183
+ * @param radians - Angle in radians
184
+ * @returns Angle in degrees
185
+ *
186
+ * @example
187
+ * ```ts
188
+ * radToDeg(Math.PI) // 180
189
+ * radToDeg(Math.PI / 2) // 90
190
+ * ```
191
+ */
192
+ export function radToDeg(radians: number): number {
193
+ return (radians * 180) / Math.PI
194
+ }
195
+
196
+ /**
197
+ * Calculates the distance between two 2D points.
198
+ *
199
+ * @param x1 - First point X
200
+ * @param y1 - First point Y
201
+ * @param x2 - Second point X
202
+ * @param y2 - Second point Y
203
+ * @returns The distance
204
+ *
205
+ * @example
206
+ * ```ts
207
+ * distance(0, 0, 3, 4) // 5
208
+ * ```
209
+ */
210
+ export function distance(
211
+ x1: number,
212
+ y1: number,
213
+ x2: number,
214
+ y2: number
215
+ ): number {
216
+ return Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)
217
+ }
218
+
219
+ /**
220
+ * Normalizes a value to a 0-1 range.
221
+ *
222
+ * @param min - Range minimum
223
+ * @param max - Range maximum
224
+ * @param value - Value to normalize
225
+ * @returns Normalized value (0-1)
226
+ *
227
+ * @example
228
+ * ```ts
229
+ * normalize(0, 100, 50) // 0.5
230
+ * normalize(0, 100, 0) // 0
231
+ * normalize(0, 100, 100) // 1
232
+ * ```
233
+ */
234
+ export function normalize(min: number, max: number, value: number): number {
235
+ return (value - min) / (max - min)
236
+ }
@@ -1,5 +1,4 @@
1
- import type { Metadata } from "next";
2
- import { getBaseUrl } from "@/lib/utils/url";
1
+ import type { Metadata } from "next"
3
2
 
4
3
  /**
5
4
  * Metadata Generation Utilities
@@ -9,25 +8,25 @@ import { getBaseUrl } from "@/lib/utils/url";
9
8
  */
10
9
 
11
10
  interface GenerateMetadataOptions {
12
- title?: string;
13
- description?: string;
14
- keywords?: string[];
11
+ title?: string
12
+ description?: string
13
+ keywords?: string[]
15
14
  image?: {
16
- url?: string;
17
- width?: number;
18
- height?: number;
19
- alt?: string;
20
- };
21
- url?: string;
22
- siteName?: string;
23
- noIndex?: boolean;
24
- type?: "website" | "article";
25
- publishedTime?: string;
26
- modifiedTime?: string;
27
- authors?: string[];
15
+ url?: string
16
+ width?: number
17
+ height?: number
18
+ alt?: string
19
+ }
20
+ url?: string
21
+ siteName?: string
22
+ noIndex?: boolean
23
+ type?: "website" | "article"
24
+ publishedTime?: string
25
+ modifiedTime?: string
26
+ authors?: string[]
28
27
  }
29
28
 
30
- const APP_BASE_URL = getBaseUrl();
29
+ const APP_BASE_URL = process.env.NEXT_PUBLIC_BASE_URL ?? "http://localhost:3000"
31
30
 
32
31
  /**
33
32
  * Generate complete metadata object for pages
@@ -62,13 +61,13 @@ export function generatePageMetadata(
62
61
  publishedTime,
63
62
  modifiedTime,
64
63
  authors,
65
- } = options;
64
+ } = options
66
65
 
67
- const fullUrl = url ? `${APP_BASE_URL}${url}` : APP_BASE_URL;
68
- const imageUrl = image?.url || "/opengraph-image.jpg";
69
- const imageWidth = image?.width || 1200;
70
- const imageHeight = image?.height || 630;
71
- const imageAlt = image?.alt || title || siteName;
66
+ const fullUrl = url ? `${APP_BASE_URL}${url}` : APP_BASE_URL
67
+ const imageUrl = image?.url || "/opengraph-image.jpg"
68
+ const imageWidth = image?.width || 1200
69
+ const imageHeight = image?.height || 630
70
+ const imageAlt = image?.alt || title || siteName
72
71
 
73
72
  const metadata: Metadata = {
74
73
  metadataBase: new URL(APP_BASE_URL),
@@ -113,14 +112,14 @@ export function generatePageMetadata(
113
112
  other: {
114
113
  "fb:app_id": process.env.NEXT_PUBLIC_FACEBOOK_APP_ID || "",
115
114
  },
116
- };
115
+ }
117
116
 
118
117
  if (noIndex) {
119
118
  metadata.robots = {
120
119
  index: false,
121
120
  follow: false,
122
- };
121
+ }
123
122
  }
124
123
 
125
- return metadata;
124
+ return metadata
126
125
  }
@@ -0,0 +1,246 @@
1
+ /**
2
+ * String & Object Utilities
3
+ *
4
+ * Helper functions for string manipulation, object operations, and refs.
5
+ */
6
+
7
+ import type { Ref } from "react"
8
+
9
+ // =============================================================================
10
+ // STRING UTILITIES
11
+ // =============================================================================
12
+
13
+ /**
14
+ * Converts text to URL-friendly slug format.
15
+ *
16
+ * @param text - Text to convert (must have toString method)
17
+ * @returns URL-safe slug string
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * slugify('Hello World!') // 'hello-world'
22
+ * slugify('Café & Restaurant') // 'cafe-restaurant'
23
+ * ```
24
+ */
25
+ export function slugify(text: { toString: () => string }) {
26
+ return text
27
+ .toString()
28
+ .normalize("NFKD")
29
+ .toLowerCase()
30
+ .trim()
31
+ .replace(/\s+/g, "-")
32
+ .replace(/[^\w-]+/g, "")
33
+ .replace(/--+/g, "-")
34
+ }
35
+
36
+ /**
37
+ * Converts first character to lowercase (camelCase format).
38
+ *
39
+ * @param inputString - String to convert
40
+ * @returns String with lowercase first character
41
+ *
42
+ * @example
43
+ * ```ts
44
+ * convertToCamelCase('HelloWorld') // 'helloWorld'
45
+ * ```
46
+ */
47
+ export function convertToCamelCase(inputString: string) {
48
+ return inputString.charAt(0).toLowerCase() + inputString.slice(1)
49
+ }
50
+
51
+ /**
52
+ * Capitalizes the first letter of a string.
53
+ *
54
+ * @param inputString - String to capitalize
55
+ * @returns String with capitalized first letter
56
+ *
57
+ * @example
58
+ * ```ts
59
+ * capitalizeFirstLetter('hello') // 'Hello'
60
+ * capitalizeFirstLetter('world') // 'World'
61
+ * ```
62
+ */
63
+ export function capitalizeFirstLetter(inputString: string) {
64
+ return inputString.charAt(0).toUpperCase() + inputString.slice(1)
65
+ }
66
+
67
+ /**
68
+ * Formats a number as a two-digit string (padding with zero).
69
+ *
70
+ * @param number - Number to format
71
+ * @returns Two-digit string representation
72
+ *
73
+ * @example
74
+ * ```ts
75
+ * twoDigits(5) // '05'
76
+ * twoDigits(23) // '23'
77
+ * ```
78
+ */
79
+ export function twoDigits(number: number) {
80
+ return number > 9 ? `${number}` : `0${number}`
81
+ }
82
+
83
+ /**
84
+ * Adds commas as thousands separators to numbers.
85
+ *
86
+ * @param x - Number to format (must have toString method)
87
+ * @returns String with comma separators
88
+ *
89
+ * @example
90
+ * ```ts
91
+ * numberWithCommas(1234) // '1,234'
92
+ * numberWithCommas(1234567) // '1,234,567'
93
+ * ```
94
+ */
95
+ export function numberWithCommas(x: { toString: () => string }) {
96
+ return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")
97
+ }
98
+
99
+ // =============================================================================
100
+ // ARRAY & OBJECT UTILITIES
101
+ // =============================================================================
102
+
103
+ export function checkIsArray<T>(value: T): T extends unknown[] ? T[0] : T {
104
+ return (Array.isArray(value) ? value[0] : value) as T extends unknown[]
105
+ ? T[0]
106
+ : T
107
+ }
108
+
109
+ /**
110
+ * Checks if an object is empty (has no enumerable properties).
111
+ *
112
+ * @param obj - Object to check
113
+ * @returns True if object is empty or null/undefined
114
+ *
115
+ * @example
116
+ * ```ts
117
+ * isEmptyObject({}) // true
118
+ * isEmptyObject({ a: 1 }) // false
119
+ * isEmptyObject(null) // true
120
+ * ```
121
+ */
122
+ export function isEmptyObject(obj: Record<string, unknown>) {
123
+ if (!obj) return true
124
+ return Object.keys(obj).length === 0
125
+ }
126
+
127
+ /**
128
+ * Checks if an array is empty or if the input is not an array.
129
+ *
130
+ * @param arr - Array or value to check
131
+ * @returns True if empty array or not an array
132
+ *
133
+ * @example
134
+ * ```ts
135
+ * isEmptyArray([]) // true
136
+ * isEmptyArray([1, 2]) // false
137
+ * isEmptyArray('test') // true (not an array)
138
+ * isEmptyArray(null) // true
139
+ * ```
140
+ */
141
+ export function isEmptyArray(arr: string | unknown[]) {
142
+ if (!arr) return true
143
+ return Array.isArray(arr) && arr.length === 0
144
+ }
145
+
146
+ export function arraytoObject(array: Record<string, unknown>[]) {
147
+ return array.reduce((acc: Record<string, unknown>, currentObj) => {
148
+ const key = Object.keys(currentObj)[0]
149
+ if (key !== undefined) {
150
+ acc[key] = currentObj[key]
151
+ }
152
+ return acc
153
+ }, {})
154
+ }
155
+
156
+ export function shortenObjectKeys(
157
+ obj: Record<string, unknown>,
158
+ keyword: string
159
+ ) {
160
+ const regex = new RegExp(`[^]+${keyword}(.*)`)
161
+
162
+ for (const key in obj) {
163
+ const match = key.match(regex)
164
+
165
+ if (match?.[1]) {
166
+ const newKey = convertToCamelCase(match[1])
167
+ obj[newKey] = obj[key]
168
+ delete obj[key]
169
+ }
170
+ }
171
+
172
+ return obj
173
+ }
174
+
175
+ export function filterObjectKeys(
176
+ obj: { [x: string]: unknown },
177
+ keyword: string
178
+ ) {
179
+ const newObj: { [x: string]: unknown } = {}
180
+
181
+ for (const key in obj) {
182
+ const match = key.includes(keyword)
183
+
184
+ if (match) {
185
+ newObj[key] = obj[key]
186
+ }
187
+ }
188
+
189
+ return newObj
190
+ }
191
+
192
+ export function iterableObject(
193
+ obj: { [s: string]: unknown } | ArrayLike<unknown>
194
+ ) {
195
+ return Object.entries(obj).map(([, value]) => {
196
+ return value
197
+ })
198
+ }
199
+
200
+ // =============================================================================
201
+ // REF UTILITIES
202
+ // =============================================================================
203
+
204
+ /**
205
+ * Merges multiple React refs into a single ref callback.
206
+ *
207
+ * Useful when you need to assign multiple refs to the same element,
208
+ * such as combining a local ref with a forwarded ref.
209
+ *
210
+ * @param refs - Refs to merge (functions and ref objects supported)
211
+ * @returns A ref callback that updates all provided refs
212
+ *
213
+ * @example
214
+ * ```tsx
215
+ * // Component that needs both local and forwarded ref
216
+ * function MyComponent({ ref }: { ref: React.Ref<HTMLDivElement> }) {
217
+ * const localRef = useRef<HTMLDivElement>(null)
218
+ * const mergedRef = mergeRefs(localRef, ref)
219
+ *
220
+ * return <div ref={mergedRef}>Content</div>
221
+ * }
222
+ *
223
+ * // Forward ref pattern
224
+ * const ForwardedComponent = forwardRef(MyComponent)
225
+ * ```
226
+ */
227
+ export function mergeRefs<T>(...refs: (Ref<T> | undefined)[]): Ref<T> {
228
+ return (value) => {
229
+ const cleanups = refs.reduce<VoidFunction[]>((accumulator, ref) => {
230
+ if (typeof ref === "function") {
231
+ const cleanup = ref(value)
232
+ if (typeof cleanup === "function") {
233
+ accumulator.push(cleanup)
234
+ }
235
+ } else if (ref) {
236
+ ref.current = value
237
+ }
238
+
239
+ return accumulator
240
+ }, [])
241
+
242
+ return () => {
243
+ for (const cleanup of cleanups) cleanup()
244
+ }
245
+ }
246
+ }
@@ -0,0 +1,15 @@
1
+ // Type augmentations and module declarations
2
+
3
+ // React CSS custom properties support
4
+ import "react"
5
+
6
+ declare module "react" {
7
+ interface CSSProperties {
8
+ [key: `--${string}`]: string | number
9
+ }
10
+ }
11
+
12
+ // Global window extensions
13
+ declare global {
14
+ interface Window {}
15
+ }
@@ -8,9 +8,12 @@
8
8
  * 4. localhost fallback
9
9
  */
10
10
  export function getBaseUrl(): string {
11
- if (process.env.NEXT_PUBLIC_BASE_URL) return process.env.NEXT_PUBLIC_BASE_URL;
12
- if (process.env.VERCEL_PROJECT_PRODUCTION_URL)
13
- return `https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}`;
14
- if (process.env.VERCEL_URL) return `https://${process.env.VERCEL_URL}`;
15
- return "http://localhost:3000";
11
+ if (process.env.NEXT_PUBLIC_BASE_URL) {
12
+ return process.env.NEXT_PUBLIC_BASE_URL
13
+ }
14
+ if (process.env.VERCEL_PROJECT_PRODUCTION_URL) {
15
+ return `https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}`
16
+ }
17
+ if (process.env.VERCEL_URL) return `https://${process.env.VERCEL_URL}`
18
+ return "http://localhost:3000"
16
19
  }