loopwind 0.17.0 → 0.18.0

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 (352) hide show
  1. package/REGISTRY_SETUP.md +55 -1
  2. package/dist/commands/add.d.ts.map +1 -1
  3. package/dist/commands/add.js +3 -0
  4. package/dist/commands/add.js.map +1 -1
  5. package/dist/lib/installer.d.ts +8 -0
  6. package/dist/lib/installer.d.ts.map +1 -1
  7. package/dist/lib/installer.js +48 -1
  8. package/dist/lib/installer.js.map +1 -1
  9. package/dist/sdk/index.d.ts +2 -2
  10. package/dist/sdk/index.d.ts.map +1 -1
  11. package/dist/sdk/index.js +1 -1
  12. package/dist/sdk/index.js.map +1 -1
  13. package/dist/sdk/template.d.ts +133 -0
  14. package/dist/sdk/template.d.ts.map +1 -1
  15. package/dist/sdk/template.js +198 -0
  16. package/dist/sdk/template.js.map +1 -1
  17. package/examples/code-editor-templates.ts +173 -0
  18. package/examples/nextjs-template-import.ts +58 -0
  19. package/examples/visual-builder-templates.ts +336 -0
  20. package/package.json +1 -1
  21. package/test-sdk-user-templates.mjs +469 -0
  22. package/website/.astro/integrations/_inox-tools_astro-when/types.d.ts +1 -0
  23. package/website/.astro/types.d.ts +1 -0
  24. package/website/DEPLOYMENT.md +142 -0
  25. package/website/OG_IMAGES.md +141 -0
  26. package/website/astro.config.mjs +0 -2
  27. package/website/deploy.sh +19 -0
  28. package/website/dist/.gitkeep +1 -0
  29. package/website/dist/_astro/agents.Yx-L_igG.css +1 -0
  30. package/website/dist/_routes.json +30 -0
  31. package/website/dist/_worker.js/_@astrojs-ssr-adapter.mjs +1033 -0
  32. package/website/dist/_worker.js/_astro-internal_middleware.mjs +40 -0
  33. package/website/dist/_worker.js/chunks/abap_BTmsHiP5.mjs +1 -0
  34. package/website/dist/_worker.js/chunks/actionscript-3_DmBelb1E.mjs +1 -0
  35. package/website/dist/_worker.js/chunks/ada_8-E0ahCN.mjs +1 -0
  36. package/website/dist/_worker.js/chunks/andromeeda_XI-CXx50.mjs +1 -0
  37. package/website/dist/_worker.js/chunks/angular-html_DKGh3gGH.mjs +1 -0
  38. package/website/dist/_worker.js/chunks/angular-ts_-qZGsJoA.mjs +1 -0
  39. package/website/dist/_worker.js/chunks/apache_ijTUt0Ee.mjs +1 -0
  40. package/website/dist/_worker.js/chunks/apex_agu1c6Sh.mjs +1 -0
  41. package/website/dist/_worker.js/chunks/apl_Bj2f7Art.mjs +1 -0
  42. package/website/dist/_worker.js/chunks/applescript_B_vXrOh3.mjs +1 -0
  43. package/website/dist/_worker.js/chunks/ara_DCEQ2rnh.mjs +1 -0
  44. package/website/dist/_worker.js/chunks/asciidoc_CGN_EkYS.mjs +1 -0
  45. package/website/dist/_worker.js/chunks/asm_BBWZgnDp.mjs +1 -0
  46. package/website/dist/_worker.js/chunks/astro/assets-service_j52rQLzU.mjs +721 -0
  47. package/website/dist/_worker.js/chunks/astro/server_Y5_QHO8v.mjs +2401 -0
  48. package/website/dist/_worker.js/chunks/astro-designed-error-pages_BNTLO-TA.mjs +542 -0
  49. package/website/dist/_worker.js/chunks/astro_Dr_hht3h.mjs +1 -0
  50. package/website/dist/_worker.js/chunks/aurora-x_9GHG8nSq.mjs +1 -0
  51. package/website/dist/_worker.js/chunks/awk_DHRvhXot.mjs +1 -0
  52. package/website/dist/_worker.js/chunks/ayu-dark_CcvqmEHE.mjs +1 -0
  53. package/website/dist/_worker.js/chunks/ballerina_C7SdeSZb.mjs +1 -0
  54. package/website/dist/_worker.js/chunks/bat_Dv4A3u45.mjs +1 -0
  55. package/website/dist/_worker.js/chunks/beancount_BfPf9Luv.mjs +1 -0
  56. package/website/dist/_worker.js/chunks/berry_B8rfM3lL.mjs +1 -0
  57. package/website/dist/_worker.js/chunks/bibtex_TcjYgtJM.mjs +1 -0
  58. package/website/dist/_worker.js/chunks/bicep_CrlFWCdN.mjs +1 -0
  59. package/website/dist/_worker.js/chunks/blade_lanKVYID.mjs +1 -0
  60. package/website/dist/_worker.js/chunks/bsl_BhppzXMB.mjs +1 -0
  61. package/website/dist/_worker.js/chunks/c_6FBALJTK.mjs +1 -0
  62. package/website/dist/_worker.js/chunks/cadence_2txU9LVE.mjs +1 -0
  63. package/website/dist/_worker.js/chunks/cairo_BkrFAIlP.mjs +1 -0
  64. package/website/dist/_worker.js/chunks/catppuccin-frappe_CkEqIYhU.mjs +1 -0
  65. package/website/dist/_worker.js/chunks/catppuccin-latte_DG4Gx_-v.mjs +1 -0
  66. package/website/dist/_worker.js/chunks/catppuccin-macchiato_Cwi3vCXf.mjs +1 -0
  67. package/website/dist/_worker.js/chunks/catppuccin-mocha_L9_OPlFX.mjs +1 -0
  68. package/website/dist/_worker.js/chunks/clarity_BEAe4Ulu.mjs +1 -0
  69. package/website/dist/_worker.js/chunks/clojure_VnUX6p2g.mjs +1 -0
  70. package/website/dist/_worker.js/chunks/cmake_0-SGkZEj.mjs +1 -0
  71. package/website/dist/_worker.js/chunks/cobol_92M_KGaE.mjs +1 -0
  72. package/website/dist/_worker.js/chunks/codeowners_CzMwskBv.mjs +1 -0
  73. package/website/dist/_worker.js/chunks/codeql_DWJZNHv1.mjs +1 -0
  74. package/website/dist/_worker.js/chunks/coffee_CQjKU2fh.mjs +1 -0
  75. package/website/dist/_worker.js/chunks/common-lisp_BBLWDpS5.mjs +1 -0
  76. package/website/dist/_worker.js/chunks/coq_hedRFV3D.mjs +1 -0
  77. package/website/dist/_worker.js/chunks/cpp_DlS1i6Zs.mjs +1 -0
  78. package/website/dist/_worker.js/chunks/crystal_D6n65fKV.mjs +1 -0
  79. package/website/dist/_worker.js/chunks/csharp_C6FCVFzc.mjs +1 -0
  80. package/website/dist/_worker.js/chunks/css_C5uJEgmJ.mjs +1 -0
  81. package/website/dist/_worker.js/chunks/csv_CtMYuuJl.mjs +1 -0
  82. package/website/dist/_worker.js/chunks/cue_BsPexqx6.mjs +1 -0
  83. package/website/dist/_worker.js/chunks/cypher_apzf6OBi.mjs +1 -0
  84. package/website/dist/_worker.js/chunks/d_DcvIRcgm.mjs +1 -0
  85. package/website/dist/_worker.js/chunks/dark-plus_C01ONtzj.mjs +1 -0
  86. package/website/dist/_worker.js/chunks/dart_WkzM5WrV.mjs +1 -0
  87. package/website/dist/_worker.js/chunks/dax_DjXAO5V4.mjs +1 -0
  88. package/website/dist/_worker.js/chunks/desktop_C92LCxdc.mjs +1 -0
  89. package/website/dist/_worker.js/chunks/diff_CVwM_9XJ.mjs +1 -0
  90. package/website/dist/_worker.js/chunks/docker_DPzgJf6Z.mjs +1 -0
  91. package/website/dist/_worker.js/chunks/dotenv_D_vgANvA.mjs +1 -0
  92. package/website/dist/_worker.js/chunks/dracula-soft_CLnUBwFm.mjs +1 -0
  93. package/website/dist/_worker.js/chunks/dracula_lBVpb6Lb.mjs +1 -0
  94. package/website/dist/_worker.js/chunks/dream-maker_DTLbzd_J.mjs +1 -0
  95. package/website/dist/_worker.js/chunks/edge_i54JYm3_.mjs +1 -0
  96. package/website/dist/_worker.js/chunks/elixir_BJCIjTu4.mjs +1 -0
  97. package/website/dist/_worker.js/chunks/elm_BbXD39-_.mjs +1 -0
  98. package/website/dist/_worker.js/chunks/emacs-lisp_pxa5cXaN.mjs +1 -0
  99. package/website/dist/_worker.js/chunks/erb_Ccjijeee.mjs +1 -0
  100. package/website/dist/_worker.js/chunks/erlang_B2VM_hi7.mjs +1 -0
  101. package/website/dist/_worker.js/chunks/everforest-dark_BxvIPBim.mjs +1 -0
  102. package/website/dist/_worker.js/chunks/everforest-light_B7VoyaJM.mjs +1 -0
  103. package/website/dist/_worker.js/chunks/fennel_D-uo7X6c.mjs +1 -0
  104. package/website/dist/_worker.js/chunks/fish_BjePoK3m.mjs +1 -0
  105. package/website/dist/_worker.js/chunks/fluent_C8fgkzLX.mjs +1 -0
  106. package/website/dist/_worker.js/chunks/fortran-fixed-form_D1pu5zrc.mjs +1 -0
  107. package/website/dist/_worker.js/chunks/fortran-free-form_CSGOhJD6.mjs +1 -0
  108. package/website/dist/_worker.js/chunks/fsharp_B0xy-A4Y.mjs +1 -0
  109. package/website/dist/_worker.js/chunks/gdresource_CWppjlHq.mjs +1 -0
  110. package/website/dist/_worker.js/chunks/gdscript_eQCHchcS.mjs +1 -0
  111. package/website/dist/_worker.js/chunks/gdshader_C4kxepX7.mjs +1 -0
  112. package/website/dist/_worker.js/chunks/genie_ACtQLcDW.mjs +1 -0
  113. package/website/dist/_worker.js/chunks/gherkin_BFp2uKUd.mjs +1 -0
  114. package/website/dist/_worker.js/chunks/git-commit_CLg9ZwMV.mjs +1 -0
  115. package/website/dist/_worker.js/chunks/git-rebase_DG8A80Nt.mjs +1 -0
  116. package/website/dist/_worker.js/chunks/github-dark-default_BI0EP2Kv.mjs +1 -0
  117. package/website/dist/_worker.js/chunks/github-dark-dimmed_a_NIC0Xb.mjs +1 -0
  118. package/website/dist/_worker.js/chunks/github-dark-high-contrast_jZGqT7hk.mjs +1 -0
  119. package/website/dist/_worker.js/chunks/github-dark_CHCDNd2O.mjs +1 -0
  120. package/website/dist/_worker.js/chunks/github-light-default_DRbOW5RG.mjs +1 -0
  121. package/website/dist/_worker.js/chunks/github-light-high-contrast_tn_kWutM.mjs +1 -0
  122. package/website/dist/_worker.js/chunks/github-light_D9brYzot.mjs +1 -0
  123. package/website/dist/_worker.js/chunks/gleam_Dmhu1oxW.mjs +1 -0
  124. package/website/dist/_worker.js/chunks/glimmer-js_BfZbXy8A.mjs +1 -0
  125. package/website/dist/_worker.js/chunks/glimmer-ts_B9QVICrD.mjs +1 -0
  126. package/website/dist/_worker.js/chunks/glsl_DD2PPwOs.mjs +1 -0
  127. package/website/dist/_worker.js/chunks/gnuplot_D2OYChUX.mjs +1 -0
  128. package/website/dist/_worker.js/chunks/go_DYGFTe3h.mjs +1 -0
  129. package/website/dist/_worker.js/chunks/graphql_B7XsT3nH.mjs +1 -0
  130. package/website/dist/_worker.js/chunks/groovy_BO12Uwkl.mjs +1 -0
  131. package/website/dist/_worker.js/chunks/hack_CB2_ztCP.mjs +1 -0
  132. package/website/dist/_worker.js/chunks/haml_CyfDcDD3.mjs +1 -0
  133. package/website/dist/_worker.js/chunks/handlebars_CfpxpWm2.mjs +1 -0
  134. package/website/dist/_worker.js/chunks/haskell_jUeC5uN5.mjs +1 -0
  135. package/website/dist/_worker.js/chunks/haxe_B6GxP1WB.mjs +1 -0
  136. package/website/dist/_worker.js/chunks/hcl_DwoHV2oh.mjs +1 -0
  137. package/website/dist/_worker.js/chunks/hjson_DV7cJRk4.mjs +1 -0
  138. package/website/dist/_worker.js/chunks/hlsl_BlFCscPI.mjs +1 -0
  139. package/website/dist/_worker.js/chunks/houston_COBFG1Mx.mjs +1 -0
  140. package/website/dist/_worker.js/chunks/html-derivative_C9pJ337h.mjs +1 -0
  141. package/website/dist/_worker.js/chunks/html_D1OkrZS5.mjs +1 -0
  142. package/website/dist/_worker.js/chunks/http_DIGXRqvJ.mjs +1 -0
  143. package/website/dist/_worker.js/chunks/hxml_DEwh9i-c.mjs +1 -0
  144. package/website/dist/_worker.js/chunks/hy_DDoIgW1K.mjs +1 -0
  145. package/website/dist/_worker.js/chunks/imba_B00zbHo4.mjs +1 -0
  146. package/website/dist/_worker.js/chunks/index_C1UTDwYg.mjs +1861 -0
  147. package/website/dist/_worker.js/chunks/ini_D7XQA_p8.mjs +1 -0
  148. package/website/dist/_worker.js/chunks/java_B9wdFd8K.mjs +1 -0
  149. package/website/dist/_worker.js/chunks/javascript_CLsPGOON.mjs +1 -0
  150. package/website/dist/_worker.js/chunks/jinja_jarBCAN1.mjs +1 -0
  151. package/website/dist/_worker.js/chunks/jison_oGg3J708.mjs +1 -0
  152. package/website/dist/_worker.js/chunks/json5_DlZ1Kyaa.mjs +1 -0
  153. package/website/dist/_worker.js/chunks/json_DaYk_FMp.mjs +1 -0
  154. package/website/dist/_worker.js/chunks/jsonc_DlwgfSDs.mjs +1 -0
  155. package/website/dist/_worker.js/chunks/jsonl_BbCCVaZF.mjs +1 -0
  156. package/website/dist/_worker.js/chunks/jsonnet_Dt-G75xe.mjs +1 -0
  157. package/website/dist/_worker.js/chunks/jssm_BtKFTj2A.mjs +1 -0
  158. package/website/dist/_worker.js/chunks/jsx_DDx_xAZ8.mjs +1 -0
  159. package/website/dist/_worker.js/chunks/julia_CK0lv68l.mjs +1 -0
  160. package/website/dist/_worker.js/chunks/kanagawa-dragon_BldAK3Oo.mjs +1 -0
  161. package/website/dist/_worker.js/chunks/kanagawa-lotus_DVM8FX9_.mjs +1 -0
  162. package/website/dist/_worker.js/chunks/kanagawa-wave_Dpih0AKP.mjs +1 -0
  163. package/website/dist/_worker.js/chunks/kotlin_kWneB9V_.mjs +1 -0
  164. package/website/dist/_worker.js/chunks/kusto_BKVATd95.mjs +1 -0
  165. package/website/dist/_worker.js/chunks/laserwave_BqatxsVl.mjs +1 -0
  166. package/website/dist/_worker.js/chunks/latex_LVDcGBbc.mjs +1 -0
  167. package/website/dist/_worker.js/chunks/lean_W7qo-5M2.mjs +1 -0
  168. package/website/dist/_worker.js/chunks/less_DFNwJnBH.mjs +1 -0
  169. package/website/dist/_worker.js/chunks/light-plus_Dp0AoWsO.mjs +1 -0
  170. package/website/dist/_worker.js/chunks/liquid_D24qs0pc.mjs +1 -0
  171. package/website/dist/_worker.js/chunks/log_IPWMXriF.mjs +1 -0
  172. package/website/dist/_worker.js/chunks/logo_C6KaatrQ.mjs +1 -0
  173. package/website/dist/_worker.js/chunks/lua_CwnEf-T7.mjs +1 -0
  174. package/website/dist/_worker.js/chunks/luau_Br3-CXjS.mjs +1 -0
  175. package/website/dist/_worker.js/chunks/make_UBNG-kOo.mjs +1 -0
  176. package/website/dist/_worker.js/chunks/markdown_C7mhJFCm.mjs +1 -0
  177. package/website/dist/_worker.js/chunks/marko_4tchUvI7.mjs +1 -0
  178. package/website/dist/_worker.js/chunks/material-theme-darker_SKtaNEPn.mjs +1 -0
  179. package/website/dist/_worker.js/chunks/material-theme-lighter_zOX_DZCH.mjs +1 -0
  180. package/website/dist/_worker.js/chunks/material-theme-ocean_BN9WbhdC.mjs +1 -0
  181. package/website/dist/_worker.js/chunks/material-theme-palenight_DT_covjH.mjs +1 -0
  182. package/website/dist/_worker.js/chunks/material-theme_6RpeM3kc.mjs +1 -0
  183. package/website/dist/_worker.js/chunks/matlab_DCOXsPKR.mjs +1 -0
  184. package/website/dist/_worker.js/chunks/mdc_B9gb2UFP.mjs +1 -0
  185. package/website/dist/_worker.js/chunks/mdx_DGU7Nu9u.mjs +1 -0
  186. package/website/dist/_worker.js/chunks/mermaid_B69URzsZ.mjs +1 -0
  187. package/website/dist/_worker.js/chunks/min-dark_BgxifOMI.mjs +1 -0
  188. package/website/dist/_worker.js/chunks/min-light_BrPjXxUp.mjs +1 -0
  189. package/website/dist/_worker.js/chunks/mipsasm_9U-4_t7k.mjs +1 -0
  190. package/website/dist/_worker.js/chunks/mojo_B0wt7ug3.mjs +1 -0
  191. package/website/dist/_worker.js/chunks/monokai_B6Pxpoyi.mjs +1 -0
  192. package/website/dist/_worker.js/chunks/move_1eid4CyR.mjs +1 -0
  193. package/website/dist/_worker.js/chunks/narrat_Ds6-p5JZ.mjs +1 -0
  194. package/website/dist/_worker.js/chunks/nextflow_v2N1Qlqa.mjs +1 -0
  195. package/website/dist/_worker.js/chunks/nginx_Bp9Ab2NH.mjs +1 -0
  196. package/website/dist/_worker.js/chunks/night-owl_CdwOw_sc.mjs +1 -0
  197. package/website/dist/_worker.js/chunks/nim_BXGDUe53.mjs +1 -0
  198. package/website/dist/_worker.js/chunks/nix_CUig1nJH.mjs +1 -0
  199. package/website/dist/_worker.js/chunks/noop-middleware_DlWGj5t5.mjs +10 -0
  200. package/website/dist/_worker.js/chunks/nord_SPoG1iae.mjs +1 -0
  201. package/website/dist/_worker.js/chunks/nushell_DJw1Lca8.mjs +1 -0
  202. package/website/dist/_worker.js/chunks/objective-c_Bktzl_CO.mjs +1 -0
  203. package/website/dist/_worker.js/chunks/objective-cpp_CP4DWdDp.mjs +1 -0
  204. package/website/dist/_worker.js/chunks/ocaml_CeEAs7bZ.mjs +1 -0
  205. package/website/dist/_worker.js/chunks/one-dark-pro_-hIwCNMi.mjs +1 -0
  206. package/website/dist/_worker.js/chunks/one-light_DSmYvJ05.mjs +1 -0
  207. package/website/dist/_worker.js/chunks/pascal_C-S_Ms_o.mjs +1 -0
  208. package/website/dist/_worker.js/chunks/perl_CKamvo15.mjs +1 -0
  209. package/website/dist/_worker.js/chunks/php_BlmcX_F3.mjs +1 -0
  210. package/website/dist/_worker.js/chunks/plastic_Ryt8tVoA.mjs +1 -0
  211. package/website/dist/_worker.js/chunks/plsql_Cb3v7cBj.mjs +1 -0
  212. package/website/dist/_worker.js/chunks/po_DZbdNRlo.mjs +1 -0
  213. package/website/dist/_worker.js/chunks/poimandres_bYmE3_5d.mjs +1 -0
  214. package/website/dist/_worker.js/chunks/polar_pJkMGwoW.mjs +1 -0
  215. package/website/dist/_worker.js/chunks/postcss_BAXSOKgk.mjs +1 -0
  216. package/website/dist/_worker.js/chunks/powerquery_oITMGN4x.mjs +1 -0
  217. package/website/dist/_worker.js/chunks/powershell_6306-xIF.mjs +1 -0
  218. package/website/dist/_worker.js/chunks/prisma_DSDxnZGz.mjs +1 -0
  219. package/website/dist/_worker.js/chunks/prolog_CxG7tjZR.mjs +1 -0
  220. package/website/dist/_worker.js/chunks/proto_CS9ByXm1.mjs +1 -0
  221. package/website/dist/_worker.js/chunks/pug_BMtLJo6U.mjs +1 -0
  222. package/website/dist/_worker.js/chunks/puppet_BfeeSzee.mjs +1 -0
  223. package/website/dist/_worker.js/chunks/purescript_BFfueNaH.mjs +1 -0
  224. package/website/dist/_worker.js/chunks/python_Cc4Faapv.mjs +1 -0
  225. package/website/dist/_worker.js/chunks/qml_C1CTJTK8.mjs +1 -0
  226. package/website/dist/_worker.js/chunks/qmldir_nG1KaqKR.mjs +1 -0
  227. package/website/dist/_worker.js/chunks/qss_Cncxk263.mjs +1 -0
  228. package/website/dist/_worker.js/chunks/r_ChR54Ihi.mjs +1 -0
  229. package/website/dist/_worker.js/chunks/racket_BDrhptDs.mjs +1 -0
  230. package/website/dist/_worker.js/chunks/raku_07OUHa0P.mjs +1 -0
  231. package/website/dist/_worker.js/chunks/razor_DIP3INLa.mjs +1 -0
  232. package/website/dist/_worker.js/chunks/red_DOPXfj-6.mjs +1 -0
  233. package/website/dist/_worker.js/chunks/reg_B64SwEDj.mjs +1 -0
  234. package/website/dist/_worker.js/chunks/regexp_ButFGoB5.mjs +1 -0
  235. package/website/dist/_worker.js/chunks/rel_BWJAWqZD.mjs +1 -0
  236. package/website/dist/_worker.js/chunks/riscv_79gXlbsF.mjs +1 -0
  237. package/website/dist/_worker.js/chunks/rose-pine-dawn_DHIjVGd3.mjs +1 -0
  238. package/website/dist/_worker.js/chunks/rose-pine-moon_t86aEbs0.mjs +1 -0
  239. package/website/dist/_worker.js/chunks/rose-pine_BHgrcDCs.mjs +1 -0
  240. package/website/dist/_worker.js/chunks/rst_D3F4Fcpj.mjs +1 -0
  241. package/website/dist/_worker.js/chunks/ruby_Cs7vM9iv.mjs +1 -0
  242. package/website/dist/_worker.js/chunks/rust_DpyRVatH.mjs +1 -0
  243. package/website/dist/_worker.js/chunks/sas_DW45xZXN.mjs +1 -0
  244. package/website/dist/_worker.js/chunks/sass_C6SiMwN_.mjs +1 -0
  245. package/website/dist/_worker.js/chunks/scala_DlZOjNZk.mjs +1 -0
  246. package/website/dist/_worker.js/chunks/scheme_D2ezSJXu.mjs +1 -0
  247. package/website/dist/_worker.js/chunks/scss_DG5Spjqu.mjs +1 -0
  248. package/website/dist/_worker.js/chunks/sdbl_ZCYaj4VN.mjs +1 -0
  249. package/website/dist/_worker.js/chunks/shaderlab_CAcRkg1_.mjs +1 -0
  250. package/website/dist/_worker.js/chunks/shellscript_BWwhkDVh.mjs +1 -0
  251. package/website/dist/_worker.js/chunks/shellsession_BfEA3juK.mjs +1 -0
  252. package/website/dist/_worker.js/chunks/slack-dark_CL3lSpCc.mjs +1 -0
  253. package/website/dist/_worker.js/chunks/slack-ochin_DdZKOQVh.mjs +1 -0
  254. package/website/dist/_worker.js/chunks/smalltalk_DgilzSui.mjs +1 -0
  255. package/website/dist/_worker.js/chunks/snazzy-light_eJU08Pz_.mjs +1 -0
  256. package/website/dist/_worker.js/chunks/solarized-dark_Dg_YQywx.mjs +1 -0
  257. package/website/dist/_worker.js/chunks/solarized-light_BnIsrA6p.mjs +1 -0
  258. package/website/dist/_worker.js/chunks/solidity_DkseH8pQ.mjs +1 -0
  259. package/website/dist/_worker.js/chunks/soy_DU7bOYoG.mjs +1 -0
  260. package/website/dist/_worker.js/chunks/sparql_BuI1DBDH.mjs +1 -0
  261. package/website/dist/_worker.js/chunks/splunk_B8Ha9Pkg.mjs +1 -0
  262. package/website/dist/_worker.js/chunks/sql_BniHwea5.mjs +1 -0
  263. package/website/dist/_worker.js/chunks/ssh-config_CkE1GuVe.mjs +1 -0
  264. package/website/dist/_worker.js/chunks/stata_Dtqpbd_l.mjs +1 -0
  265. package/website/dist/_worker.js/chunks/stylus_CXTtglzO.mjs +1 -0
  266. package/website/dist/_worker.js/chunks/svelte_BjWYcUCN.mjs +1 -0
  267. package/website/dist/_worker.js/chunks/swift_BzHql_rM.mjs +1 -0
  268. package/website/dist/_worker.js/chunks/synthwave-84_DLRNhxNA.mjs +1 -0
  269. package/website/dist/_worker.js/chunks/system-verilog_ChyInPph.mjs +1 -0
  270. package/website/dist/_worker.js/chunks/systemd_Bi9Qa2qD.mjs +1 -0
  271. package/website/dist/_worker.js/chunks/talonscript_B3sH_Y-V.mjs +1 -0
  272. package/website/dist/_worker.js/chunks/tasl_BJ5yipRs.mjs +1 -0
  273. package/website/dist/_worker.js/chunks/tcl_CoJQjNoP.mjs +1 -0
  274. package/website/dist/_worker.js/chunks/templ_CrU7Ffil.mjs +1 -0
  275. package/website/dist/_worker.js/chunks/terraform_DT9JSFpC.mjs +1 -0
  276. package/website/dist/_worker.js/chunks/tex_5PKu2yA0.mjs +1 -0
  277. package/website/dist/_worker.js/chunks/tokyo-night_Buo8OK7-.mjs +1 -0
  278. package/website/dist/_worker.js/chunks/toml_CPuXX3oc.mjs +1 -0
  279. package/website/dist/_worker.js/chunks/ts-tags_D0M_1VSH.mjs +1 -0
  280. package/website/dist/_worker.js/chunks/tsv_CuivVNot.mjs +1 -0
  281. package/website/dist/_worker.js/chunks/tsx_MkuGr8MY.mjs +1 -0
  282. package/website/dist/_worker.js/chunks/turtle_BqgEPK7f.mjs +1 -0
  283. package/website/dist/_worker.js/chunks/twig_r1G9rpYJ.mjs +1 -0
  284. package/website/dist/_worker.js/chunks/typescript_Au5buqzM.mjs +1 -0
  285. package/website/dist/_worker.js/chunks/typespec_47rhBK_z.mjs +1 -0
  286. package/website/dist/_worker.js/chunks/typst_BAtuQLh-.mjs +1 -0
  287. package/website/dist/_worker.js/chunks/v_BIvWImHg.mjs +1 -0
  288. package/website/dist/_worker.js/chunks/vala_DYEacj30.mjs +1 -0
  289. package/website/dist/_worker.js/chunks/vb_CikQuqGJ.mjs +1 -0
  290. package/website/dist/_worker.js/chunks/verilog_BQRENwI-.mjs +1 -0
  291. package/website/dist/_worker.js/chunks/vesper_DA0kvTmj.mjs +1 -0
  292. package/website/dist/_worker.js/chunks/vhdl_DHscJIyg.mjs +1 -0
  293. package/website/dist/_worker.js/chunks/viml_F2pvMwvG.mjs +1 -0
  294. package/website/dist/_worker.js/chunks/vitesse-black_D9tjNzd0.mjs +1 -0
  295. package/website/dist/_worker.js/chunks/vitesse-dark_Bnm5d0hd.mjs +1 -0
  296. package/website/dist/_worker.js/chunks/vitesse-light_CHwbyjNR.mjs +1 -0
  297. package/website/dist/_worker.js/chunks/vue-html_DyYtbbMK.mjs +1 -0
  298. package/website/dist/_worker.js/chunks/vue_DofN6juy.mjs +1 -0
  299. package/website/dist/_worker.js/chunks/vyper_CiR0m-OV.mjs +1 -0
  300. package/website/dist/_worker.js/chunks/wasm_CwIGgRGf.mjs +1 -0
  301. package/website/dist/_worker.js/chunks/wasm_jKWhg0J0.mjs +1 -0
  302. package/website/dist/_worker.js/chunks/wenyan_DKvVZKXW.mjs +1 -0
  303. package/website/dist/_worker.js/chunks/wgsl_BOWZY7yw.mjs +1 -0
  304. package/website/dist/_worker.js/chunks/wikitext_CXDhhHPy.mjs +1 -0
  305. package/website/dist/_worker.js/chunks/wolfram_ChkmGnW0.mjs +1 -0
  306. package/website/dist/_worker.js/chunks/xml_DXH3hHIu.mjs +1 -0
  307. package/website/dist/_worker.js/chunks/xsl_DuP2mFjg.mjs +1 -0
  308. package/website/dist/_worker.js/chunks/yaml_IGiEkTge.mjs +1 -0
  309. package/website/dist/_worker.js/chunks/zenscript_59iXGyNw.mjs +1 -0
  310. package/website/dist/_worker.js/chunks/zig_DKzb0zdT.mjs +1 -0
  311. package/website/dist/_worker.js/index.js +53 -0
  312. package/website/dist/_worker.js/manifest_BAAoOzaU.mjs +98 -0
  313. package/website/dist/_worker.js/pages/_image.astro.mjs +24 -0
  314. package/website/dist/_worker.js/pages/agents.astro.mjs +1 -0
  315. package/website/dist/_worker.js/pages/animation.astro.mjs +1 -0
  316. package/website/dist/_worker.js/pages/api/raw-markdown/_---path_.astro.mjs +44 -0
  317. package/website/dist/_worker.js/pages/config.astro.mjs +1 -0
  318. package/website/dist/_worker.js/pages/fonts.astro.mjs +1 -0
  319. package/website/dist/_worker.js/pages/getting-started.astro.mjs +1 -0
  320. package/website/dist/_worker.js/pages/helpers.astro.mjs +1 -0
  321. package/website/dist/_worker.js/pages/images.astro.mjs +1 -0
  322. package/website/dist/_worker.js/pages/index.astro.mjs +1 -0
  323. package/website/dist/_worker.js/pages/llm.txt.astro.mjs +1 -0
  324. package/website/dist/_worker.js/pages/preview.astro.mjs +1 -0
  325. package/website/dist/_worker.js/pages/sdk.astro.mjs +1 -0
  326. package/website/dist/_worker.js/pages/sitemap.xml.astro.mjs +1 -0
  327. package/website/dist/_worker.js/pages/styling.astro.mjs +1 -0
  328. package/website/dist/_worker.js/pages/templates.astro.mjs +1 -0
  329. package/website/dist/_worker.js/pages/video.astro.mjs +1 -0
  330. package/website/dist/_worker.js/renderers.mjs +57 -0
  331. package/website/dist/agents/index.html +3 -2
  332. package/website/dist/animation/index.html +402 -128
  333. package/website/dist/config/index.html +184 -0
  334. package/website/dist/fonts/index.html +56 -52
  335. package/website/dist/getting-started/index.html +107 -0
  336. package/website/dist/helpers/index.html +8 -8
  337. package/website/dist/images/index.html +50 -23
  338. package/website/dist/index.html +114 -148
  339. package/website/dist/llm.txt +751 -1055
  340. package/website/dist/preview/index.html +111 -0
  341. package/website/dist/robots.txt +35 -0
  342. package/website/dist/sdk/index.html +390 -52
  343. package/website/dist/sitemap.xml +76 -0
  344. package/website/dist/styling/index.html +10 -7
  345. package/website/dist/templates/index.html +11 -59
  346. package/website/dist/video/index.html +106 -537
  347. package/website/package.json +1 -5
  348. package/website/public/.assetsignore +3 -0
  349. package/website/public/.gitkeep +0 -1
  350. package/website/templates/og-image.tsx +61 -0
  351. package/website/wrangler.toml +12 -0
  352. package/website/dist/_astro/agents.I1-fN38o.css +0 -1
@@ -0,0 +1,469 @@
1
+ /**
2
+ * Test suite for user-generated templates
3
+ * - defineTemplateFromSource (code editor)
4
+ * - defineTemplateFromSchema (visual builder)
5
+ */
6
+
7
+ import { defineTemplateFromSource, defineTemplateFromSchema, renderImage, renderVideo } from './dist/sdk/index.js';
8
+ import React from 'react';
9
+ import fs from 'fs/promises';
10
+
11
+ const h = React.createElement;
12
+ let passed = 0;
13
+ let failed = 0;
14
+
15
+ function test(name, fn) {
16
+ try {
17
+ fn();
18
+ console.log(`✓ ${name}`);
19
+ passed++;
20
+ } catch (error) {
21
+ console.error(`✗ ${name}`);
22
+ console.error(` ${error.message}`);
23
+ failed++;
24
+ }
25
+ }
26
+
27
+ async function asyncTest(name, fn) {
28
+ try {
29
+ await fn();
30
+ console.log(`✓ ${name}`);
31
+ passed++;
32
+ } catch (error) {
33
+ console.error(`✗ ${name}`);
34
+ console.error(` ${error.message}`);
35
+ failed++;
36
+ }
37
+ }
38
+
39
+ console.log('Testing defineTemplateFromSource\n');
40
+
41
+ // Test 1: Basic source template
42
+ await asyncTest('Source: Basic image template', async () => {
43
+ const source = `
44
+ export const meta = {
45
+ name: 'test',
46
+ type: 'image',
47
+ size: { width: 100, height: 100 }
48
+ };
49
+
50
+ export default ({ tw }) => {
51
+ const h = React.createElement;
52
+ return h('div', { style: tw('bg-blue-500 w-full h-full') });
53
+ };
54
+ `;
55
+
56
+ const template = defineTemplateFromSource(source);
57
+ if (template.name !== 'test') throw new Error('Template name incorrect');
58
+ if (template.type !== 'image') throw new Error('Template type incorrect');
59
+
60
+ const png = await renderImage(template, {});
61
+ if (!Buffer.isBuffer(png)) throw new Error('Should return buffer');
62
+ });
63
+
64
+ // Test 2: Source template with props
65
+ await asyncTest('Source: Template with props', async () => {
66
+ const source = `
67
+ export const meta = {
68
+ name: 'with-props',
69
+ type: 'image',
70
+ size: { width: 200, height: 100 }
71
+ };
72
+
73
+ export default ({ tw, title }) => {
74
+ const h = React.createElement;
75
+ return h('div', { style: tw('flex flex-col bg-white p-4') },
76
+ h('h1', { style: tw('text-black') }, title)
77
+ );
78
+ };
79
+ `;
80
+
81
+ const template = defineTemplateFromSource(source);
82
+ const png = await renderImage(template, { title: 'Hello' });
83
+ if (!Buffer.isBuffer(png)) throw new Error('Should return buffer');
84
+ });
85
+
86
+ // Test 3: Source template with config
87
+ await asyncTest('Source: Template with config', async () => {
88
+ const source = `
89
+ export const meta = {
90
+ name: 'with-config',
91
+ type: 'image',
92
+ size: { width: 200, height: 100 }
93
+ };
94
+
95
+ export default ({ tw }) => {
96
+ const h = React.createElement;
97
+ return h('div', { style: tw('bg-primary p-4') });
98
+ };
99
+ `;
100
+
101
+ const template = defineTemplateFromSource(source, {
102
+ config: {
103
+ colors: { primary: '#ff0000' },
104
+ },
105
+ });
106
+
107
+ const svg = await renderImage(template, {}, { format: 'svg' });
108
+ const svgStr = svg.toString();
109
+ if (!svgStr.includes('#ff0000')) throw new Error('Config colors not applied');
110
+ });
111
+
112
+ // Test 4: Source video template
113
+ await asyncTest('Source: Video template', async () => {
114
+ const source = `
115
+ export const meta = {
116
+ name: 'video-test',
117
+ type: 'video',
118
+ size: { width: 100, height: 100 },
119
+ video: { fps: 2, duration: 0.5 }
120
+ };
121
+
122
+ export default ({ tw }) => {
123
+ const h = React.createElement;
124
+ return h('div', {
125
+ style: tw('bg-blue-500 w-full h-full enter-fade-in/0/500')
126
+ });
127
+ };
128
+ `;
129
+
130
+ const template = defineTemplateFromSource(source);
131
+ if (template.type !== 'video') throw new Error('Should be video type');
132
+
133
+ const mp4 = await renderVideo(template, {});
134
+ if (!Buffer.isBuffer(mp4)) throw new Error('Should return buffer');
135
+ if (mp4.length === 0) throw new Error('Video should have content');
136
+ });
137
+
138
+ // Test 5: Invalid source - no meta
139
+ test('Source: Error on missing meta', () => {
140
+ const source = `
141
+ export default () => {
142
+ return React.createElement('div', {}, 'test');
143
+ };
144
+ `;
145
+
146
+ try {
147
+ defineTemplateFromSource(source);
148
+ throw new Error('Should have thrown error');
149
+ } catch (error) {
150
+ if (!error.message.includes('meta')) throw new Error('Should mention meta');
151
+ }
152
+ });
153
+
154
+ // Test 6: Invalid source - no default export
155
+ test('Source: Error on missing default export', () => {
156
+ const source = `
157
+ export const meta = {
158
+ name: 'test',
159
+ size: { width: 100, height: 100 }
160
+ };
161
+ `;
162
+
163
+ try {
164
+ defineTemplateFromSource(source);
165
+ throw new Error('Should have thrown error');
166
+ } catch (error) {
167
+ if (!error.message.includes('default')) throw new Error('Should mention default export');
168
+ }
169
+ });
170
+
171
+ console.log('\nTesting defineTemplateFromSchema\n');
172
+
173
+ // Test 7: Basic schema template
174
+ await asyncTest('Schema: Basic template', async () => {
175
+ const schema = {
176
+ name: 'basic-schema',
177
+ size: { width: 200, height: 100 },
178
+ elements: [
179
+ {
180
+ type: 'div',
181
+ className: 'bg-blue-500 w-full h-full',
182
+ },
183
+ ],
184
+ };
185
+
186
+ const template = defineTemplateFromSchema(schema);
187
+ if (template.name !== 'basic-schema') throw new Error('Name incorrect');
188
+
189
+ const png = await renderImage(template, {});
190
+ if (!Buffer.isBuffer(png)) throw new Error('Should return buffer');
191
+ });
192
+
193
+ // Test 8: Schema with text interpolation
194
+ await asyncTest('Schema: Text interpolation', async () => {
195
+ const schema = {
196
+ name: 'with-text',
197
+ size: { width: 300, height: 150 },
198
+ elements: [
199
+ {
200
+ type: 'div',
201
+ className: 'flex flex-col bg-white p-4 w-full h-full',
202
+ children: [
203
+ {
204
+ type: 'h1',
205
+ className: 'text-black',
206
+ content: '{{title}}',
207
+ },
208
+ ],
209
+ },
210
+ ],
211
+ };
212
+
213
+ const template = defineTemplateFromSchema(schema);
214
+ const svg = await renderImage(template, { title: 'Test Title' }, { format: 'svg' });
215
+ // SVG renders text as paths, so we can't check for literal strings
216
+ // Just verify it renders without error and has content
217
+ if (!Buffer.isBuffer(svg)) throw new Error('Should return buffer');
218
+ if (svg.length === 0) throw new Error('Should have content');
219
+ });
220
+
221
+ // Test 9: Schema with nested children
222
+ await asyncTest('Schema: Nested elements', async () => {
223
+ const schema = {
224
+ name: 'nested',
225
+ size: { width: 400, height: 200 },
226
+ elements: [
227
+ {
228
+ type: 'div',
229
+ className: 'flex flex-col w-full h-full bg-white p-4',
230
+ children: [
231
+ {
232
+ type: 'h1',
233
+ className: 'text-2xl font-bold',
234
+ content: '{{title}}',
235
+ },
236
+ {
237
+ type: 'p',
238
+ className: 'text-base',
239
+ content: '{{description}}',
240
+ },
241
+ ],
242
+ },
243
+ ],
244
+ };
245
+
246
+ const template = defineTemplateFromSchema(schema);
247
+ const svg = await renderImage(
248
+ template,
249
+ { title: 'Nested', description: 'Works!' },
250
+ { format: 'svg' }
251
+ );
252
+ // SVG renders text as paths, just verify it has content
253
+ if (!Buffer.isBuffer(svg)) throw new Error('Should return buffer');
254
+ if (svg.length === 0) throw new Error('Should have content');
255
+ });
256
+
257
+ // Test 10: Schema with config
258
+ await asyncTest('Schema: With config', async () => {
259
+ const schema = {
260
+ name: 'with-config',
261
+ size: { width: 200, height: 100 },
262
+ config: {
263
+ colors: {
264
+ primary: '#00ff00',
265
+ background: '#ffffff',
266
+ },
267
+ },
268
+ elements: [
269
+ {
270
+ type: 'div',
271
+ className: 'bg-primary w-full h-full',
272
+ },
273
+ ],
274
+ };
275
+
276
+ const template = defineTemplateFromSchema(schema);
277
+ const svg = await renderImage(template, {}, { format: 'svg' });
278
+ const svgStr = svg.toString();
279
+ if (!svgStr.includes('#00ff00')) throw new Error('Primary color not applied');
280
+ });
281
+
282
+ // Test 11: Schema with multiple root elements
283
+ await asyncTest('Schema: Multiple root elements', async () => {
284
+ const schema = {
285
+ name: 'multi-root',
286
+ size: { width: 400, height: 200 },
287
+ elements: [
288
+ {
289
+ type: 'div',
290
+ className: 'flex w-full h-full bg-white',
291
+ children: [
292
+ {
293
+ type: 'div',
294
+ className: 'flex-1 bg-red-500',
295
+ content: 'First',
296
+ },
297
+ {
298
+ type: 'div',
299
+ className: 'flex-1 bg-blue-500',
300
+ content: 'Second',
301
+ },
302
+ ],
303
+ },
304
+ ],
305
+ };
306
+
307
+ const template = defineTemplateFromSchema(schema);
308
+ const svg = await renderImage(template, {}, { format: 'svg' });
309
+ // SVG renders text as paths, just verify it has content
310
+ if (!Buffer.isBuffer(svg)) throw new Error('Should return buffer');
311
+ if (svg.length === 0) throw new Error('Should have content');
312
+ });
313
+
314
+ // Test 12: Schema video template
315
+ await asyncTest('Schema: Video template', async () => {
316
+ const schema = {
317
+ name: 'video-schema',
318
+ type: 'video',
319
+ size: { width: 100, height: 100 },
320
+ video: { fps: 2, duration: 0.5 },
321
+ elements: [
322
+ {
323
+ type: 'div',
324
+ className: 'bg-purple-500 w-full h-full',
325
+ },
326
+ ],
327
+ };
328
+
329
+ const template = defineTemplateFromSchema(schema);
330
+ if (template.type !== 'video') throw new Error('Should be video type');
331
+
332
+ const mp4 = await renderVideo(template, {});
333
+ if (!Buffer.isBuffer(mp4)) throw new Error('Should return buffer');
334
+ if (mp4.length === 0) throw new Error('Video should have content');
335
+ });
336
+
337
+ // Test 13: Schema with img element
338
+ await asyncTest('Schema: Image element with interpolation', async () => {
339
+ const schema = {
340
+ name: 'with-image',
341
+ size: { width: 400, height: 200 },
342
+ elements: [
343
+ {
344
+ type: 'div',
345
+ className: 'bg-white w-full h-full flex items-center justify-center',
346
+ children: [
347
+ {
348
+ type: 'img',
349
+ src: '{{imageUrl}}',
350
+ style: { width: '128px', height: '128px' },
351
+ },
352
+ ],
353
+ },
354
+ ],
355
+ };
356
+
357
+ const template = defineTemplateFromSchema(schema);
358
+ // Use a minimal valid 1x1 red PNG
359
+ const redPixel = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8/5+hHgAHggJ/PchI7wAAAABJRU5ErkJggg==';
360
+ const svg = await renderImage(
361
+ template,
362
+ { imageUrl: redPixel },
363
+ { format: 'svg' }
364
+ );
365
+ const svgStr = svg.toString();
366
+ if (!svgStr.includes('data:image/png')) throw new Error('Image src not interpolated');
367
+ });
368
+
369
+ // Test 14: Schema error - empty elements
370
+ test('Schema: Error on empty elements', () => {
371
+ const schema = {
372
+ name: 'empty',
373
+ size: { width: 100, height: 100 },
374
+ elements: [],
375
+ };
376
+
377
+ try {
378
+ const template = defineTemplateFromSchema(schema);
379
+ // Try to render - should fail
380
+ renderImage(template, {});
381
+ throw new Error('Should have thrown error');
382
+ } catch (error) {
383
+ if (!error.message.includes('element')) throw new Error('Should mention elements');
384
+ }
385
+ });
386
+
387
+ // Test 15: Complex real-world schema
388
+ await asyncTest('Schema: Complex real-world example', async () => {
389
+ const schema = {
390
+ name: 'og-card',
391
+ size: { width: 1200, height: 630 },
392
+ config: {
393
+ colors: {
394
+ primary: '#3b82f6',
395
+ secondary: '#8b5cf6',
396
+ background: '#ffffff',
397
+ text: '#1f2937',
398
+ },
399
+ },
400
+ elements: [
401
+ {
402
+ type: 'div',
403
+ className: 'flex w-full h-full bg-background',
404
+ children: [
405
+ {
406
+ type: 'div',
407
+ className: 'flex flex-col w-1/3 bg-primary p-8 justify-between',
408
+ children: [
409
+ {
410
+ type: 'h2',
411
+ className: 'text-2xl font-bold text-white',
412
+ content: '{{category}}',
413
+ },
414
+ {
415
+ type: 'p',
416
+ className: 'text-white/80',
417
+ content: '{{date}}',
418
+ },
419
+ ],
420
+ },
421
+ {
422
+ type: 'div',
423
+ className: 'flex flex-col flex-1 p-12 justify-center',
424
+ children: [
425
+ {
426
+ type: 'h1',
427
+ className: 'text-6xl font-bold text-text mb-4',
428
+ content: '{{title}}',
429
+ },
430
+ {
431
+ type: 'div',
432
+ className: 'w-24 h-2 bg-secondary mb-4',
433
+ },
434
+ {
435
+ type: 'p',
436
+ className: 'text-2xl text-text/70',
437
+ content: '{{description}}',
438
+ },
439
+ ],
440
+ },
441
+ ],
442
+ },
443
+ ],
444
+ };
445
+
446
+ const template = defineTemplateFromSchema(schema);
447
+ const png = await renderImage(template, {
448
+ category: 'TECHNOLOGY',
449
+ date: 'March 2024',
450
+ title: 'The Future of AI',
451
+ description: 'Exploring next-generation artificial intelligence',
452
+ });
453
+
454
+ if (!Buffer.isBuffer(png)) throw new Error('Should return buffer');
455
+ if (png.length === 0) throw new Error('Image should have content');
456
+
457
+ // Save for visual inspection
458
+ await fs.writeFile('test-complex-schema.png', png);
459
+ });
460
+
461
+ // Summary
462
+ console.log('\n' + '='.repeat(50));
463
+ console.log(`Tests passed: ${passed}`);
464
+ console.log(`Tests failed: ${failed}`);
465
+ console.log('='.repeat(50));
466
+
467
+ if (failed > 0) {
468
+ process.exit(1);
469
+ }
@@ -0,0 +1 @@
1
+ import '@inox-tools/astro-when';
@@ -1 +1,2 @@
1
1
  /// <reference types="astro/client" />
2
+ /// <reference path="integrations/_inox-tools_astro-when/types.d.ts" />
@@ -0,0 +1,142 @@
1
+ # Deployment Guide
2
+
3
+ This documentation website is configured for deployment on **Cloudflare Pages/Workers** with hybrid rendering.
4
+
5
+ ## Quick Deploy
6
+
7
+ ```bash
8
+ cd website
9
+
10
+ # Install dependencies
11
+ npm install
12
+
13
+ # Build and deploy
14
+ npm run deploy
15
+ ```
16
+
17
+ ## What's Included
18
+
19
+ ### 1. Dynamic OG Image Generation
20
+
21
+ Every documentation page automatically generates its own Open Graph image using **loopwind SDK**.
22
+
23
+ - **API Route**: `/api/og/[...slug].tsx`
24
+ - **Format**: 1200x630 PNG
25
+ - **Generation**: Pre-rendered at build time for known pages, generated on-demand for others
26
+ - **Caching**: Immutable cache headers for optimal performance
27
+
28
+ **Example URLs:**
29
+ - `/api/og/sdk` → SDK page OG image
30
+ - `/api/og/config` → Config page OG image
31
+ - `/api/og/getting-started` → Getting Started OG image
32
+
33
+ ### 2. Cloudflare Workers Adapter
34
+
35
+ - **File**: `astro.config.mjs`
36
+ - **Adapter**: `@astrojs/cloudflare`
37
+ - **Output**: Hybrid (SSG + SSR)
38
+ - **Platform**: Cloudflare Workers with Assets
39
+
40
+ ### 3. Build Configuration
41
+
42
+ The Vite config externalizes Node.js built-ins for Cloudflare compatibility:
43
+
44
+ ```javascript
45
+ vite: {
46
+ ssr: {
47
+ external: ['node:fs', 'fs', 'path', etc.],
48
+ noExternal: ['loopwind'], // Bundle loopwind SDK
49
+ },
50
+ }
51
+ ```
52
+
53
+ ## Deployment Steps
54
+
55
+ ### First Time Setup
56
+
57
+ 1. **Install Wrangler CLI** (if not already installed):
58
+ ```bash
59
+ npm install -g wrangler
60
+ ```
61
+
62
+ 2. **Login to Cloudflare**:
63
+ ```bash
64
+ npx wrangler login
65
+ ```
66
+
67
+ 3. **Build and Deploy**:
68
+ ```bash
69
+ npm run deploy
70
+ ```
71
+
72
+ ### Subsequent Deployments
73
+
74
+ Just run:
75
+
76
+ ```bash
77
+ npm run deploy
78
+ ```
79
+
80
+ Or separately:
81
+
82
+ ```bash
83
+ npm run build
84
+ npm run cf:deploy
85
+ ```
86
+
87
+ ## Environment
88
+
89
+ - **Node.js**: 18+ recommended
90
+ - **Package Manager**: npm
91
+ - **Platform**: Cloudflare Workers + Assets
92
+ - **Build Time**: ~2-3 seconds
93
+
94
+ ## Performance
95
+
96
+ - **Build**: ~2.7s
97
+ - **OG Images**: Generated at build time (< 100ms each)
98
+ - **Caching**: Immutable cache headers for all OG images
99
+ - **CDN**: Cloudflare's global network
100
+
101
+ ## Verify Deployment
102
+
103
+ After deployment, test:
104
+
105
+ 1. **Home page**: `https://your-domain.com`
106
+ 2. **OG image**: `https://your-domain.com/api/og/sdk`
107
+ 3. **API routes**: All `/api/*` routes should work
108
+
109
+ ## Troubleshooting
110
+
111
+ ### Build Fails
112
+
113
+ - Check Node.js version (18+)
114
+ - Run `npm install` to ensure dependencies are up to date
115
+ - Check `npm run build` output for errors
116
+
117
+ ### OG Images Not Generating
118
+
119
+ - Verify loopwind is installed: `npm list loopwind`
120
+ - Check `/api/og/[...slug].tsx` is present
121
+ - Test locally: `npm run dev` then visit `http://localhost:4321/api/og/sdk`
122
+
123
+ ### Cloudflare Deploy Fails
124
+
125
+ - Ensure you're logged in: `npx wrangler whoami`
126
+ - Check `wrangler.toml` configuration (should not exist for Pages)
127
+ - Verify Cloudflare account has Pages enabled
128
+
129
+ ## Local Development
130
+
131
+ ```bash
132
+ npm run dev
133
+ # Visit: http://localhost:4321
134
+ # Test OG: http://localhost:4321/api/og/sdk
135
+ ```
136
+
137
+ ## Documentation
138
+
139
+ - [loopwind SDK Docs](/sdk)
140
+ - [OG Images Setup](./OG_IMAGES.md)
141
+ - [Cloudflare Astro Guide](https://developers.cloudflare.com/workers/framework-guides/web-apps/astro/)
142
+