toiljs 0.0.4 → 0.0.6

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 (409) hide show
  1. package/.idea/prettier.xml +1 -0
  2. package/as-pect.config.js +1 -1
  3. package/build/backend/.tsbuildinfo +1 -1
  4. package/build/backend/index.js +1 -2
  5. package/build/cli/.tsbuildinfo +1 -1
  6. package/build/cli/configure.d.ts +15 -0
  7. package/build/cli/configure.js +201 -0
  8. package/build/cli/create.d.ts +4 -0
  9. package/build/cli/create.js +193 -68
  10. package/build/cli/features.d.ts +23 -0
  11. package/build/cli/features.js +85 -0
  12. package/build/cli/index.js +42 -2
  13. package/build/cli/proc.d.ts +1 -0
  14. package/build/cli/proc.js +11 -0
  15. package/build/cli/ui.js +1 -2
  16. package/build/cli/validate.d.ts +4 -0
  17. package/build/cli/validate.js +19 -0
  18. package/build/client/.tsbuildinfo +1 -1
  19. package/build/client/Link.d.ts +8 -0
  20. package/build/client/Link.js +44 -0
  21. package/build/client/NavLink.d.ts +14 -0
  22. package/build/client/NavLink.js +37 -0
  23. package/build/client/Router.d.ts +7 -0
  24. package/build/client/Router.js +55 -0
  25. package/build/client/channel/channel.d.ts +23 -0
  26. package/build/client/channel/channel.js +94 -0
  27. package/build/client/error-boundary.d.ts +16 -0
  28. package/build/client/error-boundary.js +19 -0
  29. package/build/client/head/head.d.ts +26 -0
  30. package/build/client/head/head.js +87 -0
  31. package/build/client/head.d.ts +26 -0
  32. package/build/client/head.js +87 -0
  33. package/build/client/hooks.d.ts +17 -0
  34. package/build/client/hooks.js +48 -0
  35. package/build/client/index.d.ts +18 -6
  36. package/build/client/index.js +10 -3
  37. package/build/client/lazy.d.ts +16 -0
  38. package/build/client/lazy.js +53 -0
  39. package/build/client/match.js +7 -0
  40. package/build/client/mount.d.ts +2 -0
  41. package/build/client/mount.js +13 -0
  42. package/build/client/navigation/Link.d.ts +8 -0
  43. package/build/client/navigation/Link.js +44 -0
  44. package/build/client/navigation/NavLink.d.ts +14 -0
  45. package/build/client/navigation/NavLink.js +37 -0
  46. package/build/client/navigation/navigation.d.ts +13 -0
  47. package/build/client/navigation/navigation.js +97 -0
  48. package/build/client/navigation/prefetch.d.ts +11 -0
  49. package/build/client/navigation/prefetch.js +100 -0
  50. package/build/client/navigation/scroll.d.ts +8 -0
  51. package/build/client/navigation/scroll.js +36 -0
  52. package/build/client/navigation.d.ts +13 -0
  53. package/build/client/navigation.js +97 -0
  54. package/build/client/params-context.d.ts +2 -0
  55. package/build/client/params-context.js +2 -0
  56. package/build/client/prefetch.d.ts +11 -0
  57. package/build/client/prefetch.js +100 -0
  58. package/build/client/routing/Router.d.ts +7 -0
  59. package/build/client/routing/Router.js +55 -0
  60. package/build/client/routing/error-boundary.d.ts +16 -0
  61. package/build/client/routing/error-boundary.js +19 -0
  62. package/build/client/routing/hooks.d.ts +17 -0
  63. package/build/client/routing/hooks.js +48 -0
  64. package/build/client/routing/lazy.d.ts +16 -0
  65. package/build/client/routing/lazy.js +53 -0
  66. package/build/client/routing/match.d.ts +2 -0
  67. package/build/client/routing/match.js +32 -0
  68. package/build/client/routing/mount.d.ts +2 -0
  69. package/build/client/routing/mount.js +13 -0
  70. package/build/client/routing/params-context.d.ts +2 -0
  71. package/build/client/routing/params-context.js +2 -0
  72. package/build/client/scroll.d.ts +8 -0
  73. package/build/client/scroll.js +36 -0
  74. package/build/client/types.d.ts +27 -0
  75. package/build/client/types.js +1 -0
  76. package/build/compiler/.tsbuildinfo +1 -1
  77. package/build/compiler/config.d.ts +2 -0
  78. package/build/compiler/config.js +14 -2
  79. package/build/compiler/docs.d.ts +10 -0
  80. package/build/compiler/docs.js +59 -0
  81. package/build/compiler/generate.js +144 -16
  82. package/build/compiler/index.d.ts +4 -2
  83. package/build/compiler/index.js +4 -3
  84. package/build/compiler/plugin.js +16 -1
  85. package/build/compiler/routes.js +5 -1
  86. package/build/compiler/vite.d.ts +1 -1
  87. package/build/compiler/vite.js +17 -1
  88. package/build/io/.tsbuildinfo +1 -1
  89. package/build/io/BinaryWriter.js +2 -2
  90. package/eslint.config.js +1 -1
  91. package/examples/basic/.toil/docs/cli.md +3 -0
  92. package/examples/basic/.toil/docs/client.md +3 -0
  93. package/examples/basic/.toil/docs/index.md +3 -0
  94. package/examples/basic/.toil/docs/routing.md +3 -0
  95. package/examples/basic/.toil/docs/server.md +3 -0
  96. package/examples/basic/.toil/docs/styling.md +3 -0
  97. package/examples/basic/.toil/entry.tsx +3 -8
  98. package/examples/basic/.toil/globals.ts +6 -0
  99. package/examples/basic/.toil/index.html +16 -12
  100. package/examples/basic/.toil/public/images/.gitkeep +1 -0
  101. package/examples/basic/.toil/public/images/logo.svg +37 -0
  102. package/examples/basic/.toil/public/robots.txt +2 -0
  103. package/examples/basic/.toil/routes.ts +9 -7
  104. package/examples/basic/build/client/assets/404-Bq0jNTUo.js +1 -0
  105. package/examples/basic/build/client/assets/_...slug_-CXKf6qnB.js +1 -0
  106. package/examples/basic/build/client/assets/_id_-BadAyQnb.js +1 -0
  107. package/examples/basic/build/client/assets/about-BOhoEcEO.js +1 -0
  108. package/examples/basic/build/client/assets/get-started-BIXpcjkT.js +9 -0
  109. package/examples/basic/build/client/assets/index-BmqcTaBB.js +1 -0
  110. package/examples/basic/build/client/assets/io-DEVjjaJj.js +1 -0
  111. package/examples/basic/build/client/assets/layout-DJegirdz.js +1 -0
  112. package/examples/basic/build/client/assets/react-DEQrz1q7.js +9 -0
  113. package/examples/basic/build/client/assets/rolldown-runtime-KL5VtC6j.js +1 -0
  114. package/examples/basic/build/client/assets/routes-BYWn6TxK.js +1 -0
  115. package/examples/basic/build/client/css/style.css +2 -0
  116. package/examples/basic/build/client/images/.gitkeep +1 -0
  117. package/examples/basic/build/client/images/logo.svg +37 -0
  118. package/examples/basic/build/client/index.html +17 -0
  119. package/examples/basic/build/client/robots.txt +2 -0
  120. package/examples/basic/client/404.tsx +2 -5
  121. package/examples/basic/client/components/.gitkeep +1 -0
  122. package/examples/basic/client/components/Footer.tsx +8 -0
  123. package/examples/basic/client/components/HoneycombBackground.tsx +162 -0
  124. package/examples/basic/client/layout.tsx +43 -26
  125. package/examples/basic/client/public/favicon.ico +0 -0
  126. package/examples/basic/client/public/images/.gitkeep +1 -0
  127. package/examples/basic/client/public/images/logo.svg +37 -0
  128. package/examples/basic/client/public/index.html +16 -0
  129. package/examples/basic/client/public/robots.txt +2 -0
  130. package/examples/basic/client/routes/about.tsx +1 -3
  131. package/examples/basic/client/routes/blog/[id].tsx +2 -4
  132. package/examples/basic/client/routes/docs/[...slug].tsx +3 -6
  133. package/examples/basic/client/routes/get-started.tsx +84 -0
  134. package/examples/basic/client/routes/index.tsx +74 -7
  135. package/examples/basic/client/routes/io.tsx +3 -7
  136. package/examples/basic/client/styles/main.css +461 -0
  137. package/examples/basic/client/toil.tsx +7 -0
  138. package/examples/basic/node_modules/.bin/toilinit +16 -0
  139. package/examples/basic/node_modules/.bin/toilinit.cmd +17 -0
  140. package/examples/basic/node_modules/.bin/toilinit.ps1 +28 -0
  141. package/examples/basic/node_modules/.bin/toilscript +16 -0
  142. package/examples/basic/node_modules/.bin/toilscript.cmd +17 -0
  143. package/examples/basic/node_modules/.bin/toilscript.ps1 +28 -0
  144. package/examples/basic/node_modules/.bin/wasm-as +16 -0
  145. package/examples/basic/node_modules/.bin/wasm-as.cmd +17 -0
  146. package/examples/basic/node_modules/.bin/wasm-as.ps1 +28 -0
  147. package/examples/basic/node_modules/.bin/wasm-ctor-eval +16 -0
  148. package/examples/basic/node_modules/.bin/wasm-ctor-eval.cmd +17 -0
  149. package/examples/basic/node_modules/.bin/wasm-ctor-eval.ps1 +28 -0
  150. package/examples/basic/node_modules/.bin/wasm-dis +16 -0
  151. package/examples/basic/node_modules/.bin/wasm-dis.cmd +17 -0
  152. package/examples/basic/node_modules/.bin/wasm-dis.ps1 +28 -0
  153. package/examples/basic/node_modules/.bin/wasm-merge +16 -0
  154. package/examples/basic/node_modules/.bin/wasm-merge.cmd +17 -0
  155. package/examples/basic/node_modules/.bin/wasm-merge.ps1 +28 -0
  156. package/examples/basic/node_modules/.bin/wasm-metadce +16 -0
  157. package/examples/basic/node_modules/.bin/wasm-metadce.cmd +17 -0
  158. package/examples/basic/node_modules/.bin/wasm-metadce.ps1 +28 -0
  159. package/examples/basic/node_modules/.bin/wasm-opt +16 -0
  160. package/examples/basic/node_modules/.bin/wasm-opt.cmd +17 -0
  161. package/examples/basic/node_modules/.bin/wasm-opt.ps1 +28 -0
  162. package/examples/basic/node_modules/.bin/wasm-reduce +16 -0
  163. package/examples/basic/node_modules/.bin/wasm-reduce.cmd +17 -0
  164. package/examples/basic/node_modules/.bin/wasm-reduce.ps1 +28 -0
  165. package/examples/basic/node_modules/.bin/wasm-shell +16 -0
  166. package/examples/basic/node_modules/.bin/wasm-shell.cmd +17 -0
  167. package/examples/basic/node_modules/.bin/wasm-shell.ps1 +28 -0
  168. package/examples/basic/node_modules/.bin/wasm2js +16 -0
  169. package/examples/basic/node_modules/.bin/wasm2js.cmd +17 -0
  170. package/examples/basic/node_modules/.bin/wasm2js.ps1 +28 -0
  171. package/examples/basic/node_modules/.package-lock.json +49 -1
  172. package/examples/basic/node_modules/.vite/deps/_metadata.json +9 -9
  173. package/examples/basic/node_modules/binaryen/LICENSE +201 -0
  174. package/examples/basic/node_modules/binaryen/README.md +1362 -0
  175. package/examples/basic/node_modules/binaryen/bin/package.json +3 -0
  176. package/examples/basic/node_modules/binaryen/bin/wasm-as +0 -0
  177. package/examples/basic/node_modules/binaryen/bin/wasm-ctor-eval +0 -0
  178. package/examples/basic/node_modules/binaryen/bin/wasm-dis +0 -0
  179. package/examples/basic/node_modules/binaryen/bin/wasm-merge +0 -0
  180. package/examples/basic/node_modules/binaryen/bin/wasm-metadce +0 -0
  181. package/examples/basic/node_modules/binaryen/bin/wasm-opt +0 -0
  182. package/examples/basic/node_modules/binaryen/bin/wasm-reduce +0 -0
  183. package/examples/basic/node_modules/binaryen/bin/wasm-shell +0 -0
  184. package/examples/basic/node_modules/binaryen/bin/wasm2js +0 -0
  185. package/examples/basic/node_modules/binaryen/index.d.ts +2371 -0
  186. package/examples/basic/node_modules/binaryen/index.js +30552 -0
  187. package/examples/basic/node_modules/binaryen/package.json +50 -0
  188. package/examples/basic/node_modules/long/LICENSE +202 -0
  189. package/examples/basic/node_modules/long/README.md +286 -0
  190. package/examples/basic/node_modules/long/index.d.ts +2 -0
  191. package/examples/basic/node_modules/long/index.js +1581 -0
  192. package/examples/basic/node_modules/long/package.json +58 -0
  193. package/examples/basic/node_modules/long/types.d.ts +474 -0
  194. package/examples/basic/node_modules/long/umd/index.d.ts +3 -0
  195. package/examples/basic/node_modules/long/umd/index.js +1622 -0
  196. package/examples/basic/node_modules/long/umd/package.json +3 -0
  197. package/examples/basic/node_modules/long/umd/types.d.ts +474 -0
  198. package/examples/basic/node_modules/toilscript/LICENSE +201 -0
  199. package/examples/basic/node_modules/toilscript/NOTICE +94 -0
  200. package/examples/basic/node_modules/toilscript/README.md +66 -0
  201. package/examples/basic/node_modules/toilscript/bin/toilinit.js +468 -0
  202. package/examples/basic/node_modules/toilscript/bin/toilscript.js +35 -0
  203. package/examples/basic/node_modules/toilscript/dist/cli.d.ts +4 -0
  204. package/examples/basic/node_modules/toilscript/dist/cli.generated.d.ts +10027 -0
  205. package/examples/basic/node_modules/toilscript/dist/cli.js +24474 -0
  206. package/examples/basic/node_modules/toilscript/dist/cli.js.map +7 -0
  207. package/examples/basic/node_modules/toilscript/dist/importmap.json +9 -0
  208. package/examples/basic/node_modules/toilscript/dist/toilscript.d.ts +4 -0
  209. package/examples/basic/node_modules/toilscript/dist/toilscript.generated.d.ts +11242 -0
  210. package/examples/basic/node_modules/toilscript/dist/toilscript.js +337 -0
  211. package/examples/basic/node_modules/toilscript/dist/toilscript.js.map +7 -0
  212. package/examples/basic/node_modules/toilscript/dist/transform.cjs +1 -0
  213. package/examples/basic/node_modules/toilscript/dist/transform.d.ts +1 -0
  214. package/examples/basic/node_modules/toilscript/dist/transform.js +1 -0
  215. package/examples/basic/node_modules/toilscript/dist/web.js +22 -0
  216. package/examples/basic/node_modules/toilscript/lib/binaryen.d.ts +2 -0
  217. package/examples/basic/node_modules/toilscript/lib/binaryen.js +2 -0
  218. package/examples/basic/node_modules/toilscript/package.json +115 -0
  219. package/examples/basic/node_modules/toilscript/std/README.md +6 -0
  220. package/examples/basic/node_modules/toilscript/std/assembly/array.ts +550 -0
  221. package/examples/basic/node_modules/toilscript/std/assembly/arraybuffer.ts +77 -0
  222. package/examples/basic/node_modules/toilscript/std/assembly/atomics.ts +127 -0
  223. package/examples/basic/node_modules/toilscript/std/assembly/bindings/asyncify.ts +16 -0
  224. package/examples/basic/node_modules/toilscript/std/assembly/bindings/dom.ts +291 -0
  225. package/examples/basic/node_modules/toilscript/std/assembly/bindings/node.ts +6 -0
  226. package/examples/basic/node_modules/toilscript/std/assembly/bitflags.ts +53 -0
  227. package/examples/basic/node_modules/toilscript/std/assembly/builtins.ts +2650 -0
  228. package/examples/basic/node_modules/toilscript/std/assembly/byteslice.ts +177 -0
  229. package/examples/basic/node_modules/toilscript/std/assembly/compat.ts +2 -0
  230. package/examples/basic/node_modules/toilscript/std/assembly/console.ts +42 -0
  231. package/examples/basic/node_modules/toilscript/std/assembly/crypto.ts +9 -0
  232. package/examples/basic/node_modules/toilscript/std/assembly/dataview.ts +181 -0
  233. package/examples/basic/node_modules/toilscript/std/assembly/date.ts +375 -0
  234. package/examples/basic/node_modules/toilscript/std/assembly/diagnostics.ts +11 -0
  235. package/examples/basic/node_modules/toilscript/std/assembly/encoding.ts +151 -0
  236. package/examples/basic/node_modules/toilscript/std/assembly/endian.ts +45 -0
  237. package/examples/basic/node_modules/toilscript/std/assembly/error.ts +44 -0
  238. package/examples/basic/node_modules/toilscript/std/assembly/fixedarray.ts +173 -0
  239. package/examples/basic/node_modules/toilscript/std/assembly/fixedmap.ts +326 -0
  240. package/examples/basic/node_modules/toilscript/std/assembly/fixedset.ts +275 -0
  241. package/examples/basic/node_modules/toilscript/std/assembly/function.ts +42 -0
  242. package/examples/basic/node_modules/toilscript/std/assembly/index.d.ts +2892 -0
  243. package/examples/basic/node_modules/toilscript/std/assembly/iterator.ts +35 -0
  244. package/examples/basic/node_modules/toilscript/std/assembly/map.ts +269 -0
  245. package/examples/basic/node_modules/toilscript/std/assembly/math.ts +3289 -0
  246. package/examples/basic/node_modules/toilscript/std/assembly/memory.ts +123 -0
  247. package/examples/basic/node_modules/toilscript/std/assembly/number.ts +388 -0
  248. package/examples/basic/node_modules/toilscript/std/assembly/object.ts +36 -0
  249. package/examples/basic/node_modules/toilscript/std/assembly/performance.ts +9 -0
  250. package/examples/basic/node_modules/toilscript/std/assembly/pointer.ts +80 -0
  251. package/examples/basic/node_modules/toilscript/std/assembly/polyfills.ts +27 -0
  252. package/examples/basic/node_modules/toilscript/std/assembly/process.ts +50 -0
  253. package/examples/basic/node_modules/toilscript/std/assembly/reference.ts +48 -0
  254. package/examples/basic/node_modules/toilscript/std/assembly/regexp.ts +12 -0
  255. package/examples/basic/node_modules/toilscript/std/assembly/rt/README.md +83 -0
  256. package/examples/basic/node_modules/toilscript/std/assembly/rt/common.ts +81 -0
  257. package/examples/basic/node_modules/toilscript/std/assembly/rt/index-incremental.ts +2 -0
  258. package/examples/basic/node_modules/toilscript/std/assembly/rt/index-memory.ts +1 -0
  259. package/examples/basic/node_modules/toilscript/std/assembly/rt/index-minimal.ts +2 -0
  260. package/examples/basic/node_modules/toilscript/std/assembly/rt/index-stub.ts +1 -0
  261. package/examples/basic/node_modules/toilscript/std/assembly/rt/index.d.ts +37 -0
  262. package/examples/basic/node_modules/toilscript/std/assembly/rt/itcms.ts +419 -0
  263. package/examples/basic/node_modules/toilscript/std/assembly/rt/memory-runtime.ts +94 -0
  264. package/examples/basic/node_modules/toilscript/std/assembly/rt/rtrace.ts +15 -0
  265. package/examples/basic/node_modules/toilscript/std/assembly/rt/stub.ts +133 -0
  266. package/examples/basic/node_modules/toilscript/std/assembly/rt/tcms.ts +254 -0
  267. package/examples/basic/node_modules/toilscript/std/assembly/rt/tlsf.ts +592 -0
  268. package/examples/basic/node_modules/toilscript/std/assembly/rt.ts +90 -0
  269. package/examples/basic/node_modules/toilscript/std/assembly/set.ts +225 -0
  270. package/examples/basic/node_modules/toilscript/std/assembly/shared/feature.ts +68 -0
  271. package/examples/basic/node_modules/toilscript/std/assembly/shared/runtime.ts +13 -0
  272. package/examples/basic/node_modules/toilscript/std/assembly/shared/target.ts +11 -0
  273. package/examples/basic/node_modules/toilscript/std/assembly/shared/tsconfig.json +11 -0
  274. package/examples/basic/node_modules/toilscript/std/assembly/shared/typeinfo.ts +72 -0
  275. package/examples/basic/node_modules/toilscript/std/assembly/staticarray.ts +423 -0
  276. package/examples/basic/node_modules/toilscript/std/assembly/string.ts +850 -0
  277. package/examples/basic/node_modules/toilscript/std/assembly/symbol.ts +114 -0
  278. package/examples/basic/node_modules/toilscript/std/assembly/table.ts +16 -0
  279. package/examples/basic/node_modules/toilscript/std/assembly/toilscript.ts +16 -0
  280. package/examples/basic/node_modules/toilscript/std/assembly/tsconfig.json +6 -0
  281. package/examples/basic/node_modules/toilscript/std/assembly/typedarray.ts +1954 -0
  282. package/examples/basic/node_modules/toilscript/std/assembly/uri.ts +17 -0
  283. package/examples/basic/node_modules/toilscript/std/assembly/util/bytes.ts +107 -0
  284. package/examples/basic/node_modules/toilscript/std/assembly/util/casemap.ts +497 -0
  285. package/examples/basic/node_modules/toilscript/std/assembly/util/error.ts +58 -0
  286. package/examples/basic/node_modules/toilscript/std/assembly/util/hash.ts +117 -0
  287. package/examples/basic/node_modules/toilscript/std/assembly/util/math.ts +1922 -0
  288. package/examples/basic/node_modules/toilscript/std/assembly/util/memory.ts +290 -0
  289. package/examples/basic/node_modules/toilscript/std/assembly/util/number.ts +873 -0
  290. package/examples/basic/node_modules/toilscript/std/assembly/util/sort.ts +313 -0
  291. package/examples/basic/node_modules/toilscript/std/assembly/util/string.ts +1202 -0
  292. package/examples/basic/node_modules/toilscript/std/assembly/util/uri.ts +275 -0
  293. package/examples/basic/node_modules/toilscript/std/assembly/vector.ts +4 -0
  294. package/examples/basic/node_modules/toilscript/std/assembly.json +16 -0
  295. package/examples/basic/node_modules/toilscript/std/portable/index.d.ts +461 -0
  296. package/examples/basic/node_modules/toilscript/std/portable/index.js +416 -0
  297. package/examples/basic/node_modules/toilscript/std/portable.json +11 -0
  298. package/examples/basic/node_modules/toilscript/std/types/assembly/index.d.ts +1 -0
  299. package/examples/basic/node_modules/toilscript/std/types/assembly/package.json +3 -0
  300. package/examples/basic/node_modules/toilscript/std/types/portable/index.d.ts +1 -0
  301. package/examples/basic/node_modules/toilscript/std/types/portable/package.json +3 -0
  302. package/examples/basic/node_modules/toilscript/tsconfig-base.json +13 -0
  303. package/examples/basic/node_modules/toilscript/util/README.md +23 -0
  304. package/examples/basic/node_modules/toilscript/util/browser/fs.js +1 -0
  305. package/examples/basic/node_modules/toilscript/util/browser/module.js +5 -0
  306. package/examples/basic/node_modules/toilscript/util/browser/path.js +520 -0
  307. package/examples/basic/node_modules/toilscript/util/browser/process.js +59 -0
  308. package/examples/basic/node_modules/toilscript/util/browser/url.js +23 -0
  309. package/examples/basic/node_modules/toilscript/util/cpu.d.ts +9 -0
  310. package/examples/basic/node_modules/toilscript/util/cpu.js +42 -0
  311. package/examples/basic/node_modules/toilscript/util/find.d.ts +6 -0
  312. package/examples/basic/node_modules/toilscript/util/find.js +20 -0
  313. package/examples/basic/node_modules/toilscript/util/node.d.ts +21 -0
  314. package/examples/basic/node_modules/toilscript/util/node.js +34 -0
  315. package/examples/basic/node_modules/toilscript/util/options.d.ts +70 -0
  316. package/examples/basic/node_modules/toilscript/util/options.js +262 -0
  317. package/examples/basic/node_modules/toilscript/util/terminal.d.ts +52 -0
  318. package/examples/basic/node_modules/toilscript/util/terminal.js +35 -0
  319. package/examples/basic/node_modules/toilscript/util/text.d.ts +26 -0
  320. package/examples/basic/node_modules/toilscript/util/text.js +114 -0
  321. package/examples/basic/node_modules/toilscript/util/tsconfig.json +9 -0
  322. package/examples/basic/node_modules/toilscript/util/web.d.ts +11 -0
  323. package/examples/basic/node_modules/toilscript/util/web.js +33 -0
  324. package/examples/basic/package-lock.json +50 -1
  325. package/examples/basic/package.json +5 -2
  326. package/examples/basic/server/index.ts +3 -0
  327. package/examples/basic/server/main.ts +6 -0
  328. package/examples/basic/server/tsconfig.json +7 -0
  329. package/examples/basic/toil-env.d.ts +20 -1
  330. package/examples/basic/toil.config.ts +2 -5
  331. package/examples/basic/toilconfig.json +30 -0
  332. package/package.json +2 -2
  333. package/presets/eslint.js +2 -7
  334. package/presets/no-uint8array-tostring.js +4 -5
  335. package/presets/prettier.json +8 -1
  336. package/src/backend/index.ts +11 -18
  337. package/src/cli/configure.ts +272 -0
  338. package/src/cli/create.ts +267 -82
  339. package/src/cli/features.ts +128 -0
  340. package/src/cli/index.ts +44 -3
  341. package/src/cli/proc.ts +20 -0
  342. package/src/cli/ui.ts +4 -6
  343. package/src/cli/validate.ts +31 -0
  344. package/src/client/head/head.ts +140 -0
  345. package/src/client/index.ts +39 -9
  346. package/src/client/navigation/Link.tsx +99 -0
  347. package/src/client/navigation/NavLink.tsx +86 -0
  348. package/src/client/navigation/navigation.ts +142 -0
  349. package/src/client/navigation/prefetch.ts +130 -0
  350. package/src/client/navigation/scroll.ts +53 -0
  351. package/src/client/routing/Router.tsx +95 -0
  352. package/src/client/routing/error-boundary.tsx +43 -0
  353. package/src/client/routing/hooks.ts +115 -0
  354. package/src/client/routing/lazy.ts +93 -0
  355. package/src/client/{match.ts → routing/match.ts} +11 -3
  356. package/src/client/routing/mount.tsx +28 -0
  357. package/src/client/routing/params-context.ts +10 -0
  358. package/src/client/types.ts +36 -0
  359. package/src/compiler/config.ts +26 -10
  360. package/src/compiler/docs.ts +87 -0
  361. package/src/compiler/generate.ts +180 -23
  362. package/src/compiler/index.ts +6 -4
  363. package/src/compiler/plugin.ts +22 -1
  364. package/src/compiler/routes.ts +13 -7
  365. package/src/compiler/vite.ts +28 -5
  366. package/src/io/BinaryReader.ts +1 -5
  367. package/src/io/BinaryWriter.ts +3 -3
  368. package/src/server/index.ts +3 -4
  369. package/src/server/tsconfig.json +4 -0
  370. package/templates/app/client/404.tsx +11 -0
  371. package/templates/app/client/components/.gitkeep +1 -0
  372. package/templates/app/client/components/Footer.tsx +8 -0
  373. package/templates/app/client/components/HoneycombBackground.tsx +162 -0
  374. package/templates/app/client/layout.tsx +53 -0
  375. package/templates/app/client/public/favicon.ico +0 -0
  376. package/templates/app/client/public/images/.gitkeep +1 -0
  377. package/templates/app/client/public/images/logo.svg +37 -0
  378. package/templates/app/client/public/index.html +16 -0
  379. package/templates/app/client/public/robots.txt +2 -0
  380. package/templates/app/client/routes/about.tsx +11 -0
  381. package/templates/app/client/routes/blog/[id].tsx +12 -0
  382. package/templates/app/client/routes/docs/[...slug].tsx +12 -0
  383. package/templates/app/client/routes/get-started.tsx +84 -0
  384. package/templates/app/client/routes/index.tsx +80 -0
  385. package/templates/app/client/routes/io.tsx +24 -0
  386. package/templates/app/client/styles/main.css +461 -0
  387. package/templates/app/client/toil.tsx +7 -0
  388. package/test/channel.test.ts +1 -1
  389. package/test/configure.test.ts +90 -0
  390. package/test/features.test.ts +111 -0
  391. package/test/head.test.ts +35 -0
  392. package/test/io.test.ts +8 -0
  393. package/test/navlink.test.ts +28 -0
  394. package/test/routes.test.ts +16 -1
  395. package/test/validate.test.ts +42 -0
  396. package/vitest.config.ts +1 -1
  397. package/examples/basic/dist/assets/404-D1bS2aH_.js +0 -1
  398. package/examples/basic/dist/assets/_...slug_-wR3shlWn.js +0 -1
  399. package/examples/basic/dist/assets/_id_-EWYvHfi2.js +0 -1
  400. package/examples/basic/dist/assets/about-Ddvj1tjF.js +0 -1
  401. package/examples/basic/dist/assets/index-CdG0me90.js +0 -1
  402. package/examples/basic/dist/assets/io-CODNJU57.js +0 -1
  403. package/examples/basic/dist/assets/layout-C15ZTPYI.js +0 -1
  404. package/examples/basic/dist/assets/react-JbAfoxYe.js +0 -9
  405. package/examples/basic/dist/assets/rolldown-runtime-1VNLd2iN.js +0 -1
  406. package/examples/basic/dist/assets/routes-GoydenoY.js +0 -1
  407. package/examples/basic/dist/index.html +0 -12
  408. package/src/client/runtime.tsx +0 -190
  409. /package/src/client/{channel.ts → channel/channel.ts} +0 -0
@@ -1,23 +1,34 @@
1
- import { spawn } from 'node:child_process';
2
1
  import fs from 'node:fs/promises';
3
2
  import path from 'node:path';
4
- import { intro, outro, text, select, confirm, isCancel, cancel, spinner, note } from '@clack/prompts';
5
- import { TOIL_ENV_DTS } from 'toiljs/compiler';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { intro, outro, text, select, multiselect, confirm, isCancel, cancel, spinner, note, } from '@clack/prompts';
5
+ import { AI_HELPERS, AI_HELPER_IDS, aiHelperFiles, TOIL_DOCS, TOIL_ENV_DTS } from 'toiljs/compiler';
6
6
  import pc from 'picocolors';
7
+ import { PKG_VERSION, PREPROCESSORS, requiredPackages, setStyleImports, styleEntry, styleImportLines, TAILWIND_CSS, TAILWIND_ENTRY, } from './features.js';
8
+ import { run } from './proc.js';
7
9
  import { accent, dim, version } from './ui.js';
10
+ import { isPackageManager, isValidName, resolveProjectDir } from './validate.js';
11
+ const PREPROCESSOR_LABEL = {
12
+ css: 'Plain CSS',
13
+ sass: 'Sass (SCSS)',
14
+ less: 'Less',
15
+ stylus: 'Stylus',
16
+ };
17
+ const DEFAULT_STYLE_CONTENT = ':root {\n color-scheme: dark;\n}\n\n' +
18
+ 'body {\n margin: 0;\n background: #080d11;\n color: #f5f6fa;\n' +
19
+ ' font-family: system-ui, -apple-system, sans-serif;\n line-height: 1.6;\n}\n\n' +
20
+ 'a {\n color: #2563ff;\n text-decoration: none;\n}\n\n' +
21
+ 'a:hover {\n color: #22e3ab;\n}\n\n' +
22
+ 'code {\n background: #11161f;\n color: #22e3ab;\n padding: 0.1rem 0.4rem;\n' +
23
+ ' border-radius: 4px;\n font-size: 0.9em;\n}\n\n' +
24
+ 'h1 {\n background: linear-gradient(90deg, #2563ff, #7c3aed, #22e3ab);\n' +
25
+ ' -webkit-background-clip: text;\n background-clip: text;\n color: transparent;\n}\n';
8
26
  function bail(value) {
9
27
  if (isCancel(value)) {
10
28
  cancel('Scaffolding cancelled.');
11
29
  process.exit(0);
12
30
  }
13
31
  }
14
- function isValidName(name) {
15
- if (!name.trim())
16
- return 'Please enter a project name.';
17
- if (!/^[a-z0-9._@/-]+$/i.test(name))
18
- return 'Use letters, numbers, dashes, dots or slashes.';
19
- return true;
20
- }
21
32
  async function isEmptyDir(dir) {
22
33
  try {
23
34
  const entries = await fs.readdir(dir);
@@ -27,59 +38,139 @@ async function isEmptyDir(dir) {
27
38
  return true;
28
39
  }
29
40
  }
30
- function scaffold(name, template) {
41
+ function scaffold(name, template, features, aiTools) {
31
42
  const toilVersion = version();
43
+ const devDependencies = {
44
+ '@types/react': '^19.2.15',
45
+ '@types/react-dom': '^19.2.3',
46
+ eslint: '^10.2.0',
47
+ prettier: '^3.8.1',
48
+ toilscript: '^0.1.2',
49
+ typescript: '^6.0.3',
50
+ };
51
+ for (const dep of requiredPackages(features).sort()) {
52
+ devDependencies[dep] = PKG_VERSION[dep] ?? 'latest';
53
+ }
32
54
  const pkg = {
33
55
  name: path.basename(name),
34
56
  private: true,
35
57
  type: 'module',
36
58
  scripts: {
37
59
  dev: 'toiljs dev',
38
- build: 'toiljs build',
60
+ build: 'toiljs build && toilscript --target release',
61
+ 'build:client': 'toiljs build',
62
+ 'build:server': 'toilscript --target release',
39
63
  lint: 'eslint client',
40
64
  typecheck: 'tsc --noEmit',
41
- format: 'prettier --write "client/**/*.{ts,tsx}"',
65
+ format: 'prettier --write "client/**/*.{ts,tsx,css,scss,less}" "client/public/**/*.html"',
42
66
  },
43
67
  dependencies: {
44
68
  toiljs: `^${toilVersion}`,
45
69
  react: '^19.2.6',
46
70
  'react-dom': '^19.2.6',
47
71
  },
48
- devDependencies: {
49
- '@types/react': '^19.2.15',
50
- '@types/react-dom': '^19.2.3',
51
- eslint: '^10.2.0',
52
- prettier: '^3.8.1',
53
- typescript: '^6.0.3',
54
- },
72
+ devDependencies,
55
73
  };
56
74
  const files = {
57
75
  'package.json': JSON.stringify(pkg, null, 4) + '\n',
58
76
  'toil.config.ts': "import { defineConfig } from 'toiljs/compiler';\n\n" +
59
- 'export default defineConfig({\n client: {\n outDir: \'dist\',\n },\n});\n',
77
+ 'export default defineConfig({});\n',
60
78
  'tsconfig.json': '{\n "extends": "toiljs/tsconfig",\n "include": ["client", "toil-env.d.ts"]\n}\n',
61
79
  'eslint.config.js': "import toiljs from 'toiljs/eslint';\n\nexport default toiljs;\n",
62
80
  '.prettierrc': '"toiljs/prettier"\n',
63
- '.gitignore': 'node_modules\ndist\n.toil\ntoil-env.d.ts\n',
81
+ '.gitignore': 'node_modules\nbuild\n.toil\ntoil-env.d.ts\n',
64
82
  'toil-env.d.ts': TOIL_ENV_DTS,
83
+ 'toilconfig.json': JSON.stringify({
84
+ entries: ['server/main.ts'],
85
+ targets: {
86
+ release: {
87
+ outFile: 'build/server/release.wasm',
88
+ textFile: 'build/server/release.wat',
89
+ },
90
+ },
91
+ options: {
92
+ sourceMap: false,
93
+ optimizeLevel: 3,
94
+ shrinkLevel: 1,
95
+ converge: true,
96
+ noAssert: false,
97
+ enable: [
98
+ 'sign-extension',
99
+ 'mutable-globals',
100
+ 'nontrapping-f2i',
101
+ 'bulk-memory',
102
+ 'simd',
103
+ 'reference-types',
104
+ 'multi-value',
105
+ ],
106
+ runtime: 'stub',
107
+ memoryBase: 0,
108
+ initialMemory: 1,
109
+ debug: false,
110
+ trapMode: 'allow',
111
+ },
112
+ }, null, 4) + '\n',
113
+ 'server/tsconfig.json': JSON.stringify({
114
+ extends: 'toilscript/std/assembly.json',
115
+ include: ['./**/*.ts'],
116
+ }, null, 4) + '\n',
117
+ 'server/index.ts': 'export function add(a: i32, b: i32): i32 {\n return a + b;\n}\n',
118
+ 'server/main.ts': "import { add } from './index';\n\n" +
119
+ '@main\nfunction run(): i32 {\n return add(40, 2);\n}\n',
65
120
  'README.md': ['# ' + path.basename(name), '', 'A [toiljs](https://toil.org) app.', '', '## Develop', '', ' npm install', ' npm run dev', '', '## Build', '', ' npm run build', ''].join('\n'),
121
+ };
122
+ if (template === 'minimal')
123
+ Object.assign(files, minimalClient(name, features));
124
+ Object.assign(files, aiHelperFiles(aiTools));
125
+ for (const [docName, content] of Object.entries(TOIL_DOCS)) {
126
+ files[`.toil/docs/${docName}`] = content;
127
+ }
128
+ return files;
129
+ }
130
+ function minimalClient(name, features) {
131
+ const files = {
132
+ 'client/public/index.html': '<!doctype html>\n<html lang="en">\n <head>\n' +
133
+ ' <meta charset="utf-8" />\n' +
134
+ ' <meta name="viewport" content="width=device-width, initial-scale=1" />\n' +
135
+ ' <meta name="theme-color" content="#080D11" />\n' +
136
+ ' <meta name="description" content="" />\n' +
137
+ ' <link rel="icon" type="image/svg+xml" href="/favicon.svg" />\n' +
138
+ ' <link rel="manifest" href="/manifest.webmanifest" />\n' +
139
+ ` <title>${path.basename(name)}</title>\n` +
140
+ ' </head>\n <body>\n <div id="root"></div>\n </body>\n</html>\n',
141
+ 'client/public/favicon.svg': '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">\n' +
142
+ ' <defs>\n' +
143
+ ' <linearGradient id="g" x1="0" y1="0" x2="1" y2="1">\n' +
144
+ ' <stop offset="0" stop-color="#2563FF" />\n' +
145
+ ' <stop offset="0.5" stop-color="#7C3AED" />\n' +
146
+ ' <stop offset="1" stop-color="#22E3AB" />\n' +
147
+ ' </linearGradient>\n' +
148
+ ' </defs>\n' +
149
+ ' <rect width="32" height="32" rx="7" fill="#080D11" />\n' +
150
+ ' <path d="M9 10h14v3.2h-5.4V24h-3.2V13.2H9z" fill="url(#g)" />\n' +
151
+ '</svg>\n',
152
+ 'client/public/robots.txt': 'User-agent: *\nAllow: /\n',
153
+ 'client/public/manifest.webmanifest': JSON.stringify({
154
+ name: path.basename(name),
155
+ short_name: path.basename(name),
156
+ start_url: '/',
157
+ display: 'standalone',
158
+ background_color: '#080D11',
159
+ theme_color: '#080D11',
160
+ icons: [{ src: '/favicon.svg', type: 'image/svg+xml', sizes: 'any' }],
161
+ }, null, 4) + '\n',
162
+ 'client/public/images/.gitkeep': '# Place images and other static assets here; served at /images/*.\n',
163
+ 'client/toil.tsx': "import { routes, layout, notFound } from 'toiljs/routes';\n\n" +
164
+ styleImportLines(features).join('\n') +
165
+ '\n\n' +
166
+ 'Toil.mount(routes, layout, notFound);\n',
167
+ [`client/${styleEntry(features.preprocessor)}`]: DEFAULT_STYLE_CONTENT,
168
+ 'client/components/.gitkeep': '# Place shared React components here.\n',
66
169
  'client/layout.tsx': `import { type ReactNode } from 'react';
67
170
 
68
- import { Link } from 'toiljs/client';
69
-
70
- const styles = \`
71
- :root { color-scheme: dark; }
72
- body { margin: 0; background: #080D11; color: #F5F6FA; font-family: system-ui, -apple-system, sans-serif; line-height: 1.6; }
73
- a { color: #2563FF; text-decoration: none; }
74
- a:hover { color: #22E3AB; }
75
- code { background: #11161f; color: #22E3AB; padding: 0.1rem 0.4rem; border-radius: 4px; font-size: 0.9em; }
76
- h1 { background: linear-gradient(90deg, #2563FF, #7C3AED, #22E3AB); -webkit-background-clip: text; background-clip: text; color: transparent; }
77
- \`;
78
-
79
171
  export default function Layout({ children }: { children?: ReactNode }) {
80
172
  return (
81
173
  <div style={{ maxWidth: 680, margin: '0 auto', padding: '3rem 1.5rem' }}>
82
- <style>{styles}</style>
83
174
  <header
84
175
  style={{
85
176
  display: 'flex',
@@ -91,7 +182,7 @@ export default function Layout({ children }: { children?: ReactNode }) {
91
182
  }}>
92
183
  <strong style={{ color: '#2563FF', fontSize: '1.1rem' }}>${path.basename(name)}</strong>
93
184
  <nav style={{ display: 'flex', gap: '1rem' }}>
94
- <Link href="/">home</Link>${template === 'app' ? '\n <Link href="/about">about</Link>' : ''}
185
+ <Toil.Link href="/">home</Toil.Link>
95
186
  </nav>
96
187
  </header>
97
188
  {children}
@@ -99,33 +190,32 @@ export default function Layout({ children }: { children?: ReactNode }) {
99
190
  );
100
191
  }
101
192
  `,
102
- 'client/routes/index.tsx': "import { Link } from 'toiljs/client';\n\n" +
103
- 'export default function Home() {\n' +
193
+ 'client/routes/index.tsx': 'export default function Home() {\n' +
104
194
  ' return (\n <main>\n' +
105
195
  ' <h1>Welcome to toiljs</h1>\n' +
106
196
  ' <p>File-based routing, bundled by Vite, zero config.</p>\n' +
107
- (template === 'app'
108
- ? ' <p>\n <Link href="/about">About</Link> · <Link href="/blog/42">Blog post 42</Link>\n </p>\n'
109
- : '') +
110
197
  ' </main>\n );\n}\n',
111
198
  };
112
- if (template === 'app') {
113
- files['client/routes/about.tsx'] =
114
- "import { Link } from 'toiljs/client';\n\n" +
115
- 'export default function About() {\n' +
116
- ' return (\n <main>\n <h1>About</h1>\n' +
117
- ' <p>\n This page is served by <code>client/routes/about.tsx</code>.\n </p>\n' +
118
- ' <Link href="/">Back home</Link>\n </main>\n );\n}\n';
119
- files['client/routes/blog/[id].tsx'] =
120
- "import { Link, useParams } from 'toiljs/client';\n\n" +
121
- 'export default function BlogPost() {\n' +
122
- ' const { id } = useParams();\n' +
123
- ' return (\n <main>\n <h1>Blog post {id}</h1>\n' +
124
- ' <p>\n Dynamic route from <code>client/routes/blog/[id].tsx</code>.\n </p>\n' +
125
- ' <Link href="/">Back home</Link>\n </main>\n );\n}\n';
126
- }
199
+ if (features.tailwind)
200
+ files[`client/${TAILWIND_ENTRY}`] = TAILWIND_CSS;
127
201
  return files;
128
202
  }
203
+ function templateDir(template) {
204
+ return path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..', 'templates', template);
205
+ }
206
+ async function applyStyling(clientDir, features) {
207
+ if (features.preprocessor === 'css' && !features.tailwind)
208
+ return;
209
+ const entry = styleEntry(features.preprocessor);
210
+ if (entry !== 'styles/main.css') {
211
+ await fs.rename(path.join(clientDir, 'styles', 'main.css'), path.join(clientDir, entry));
212
+ }
213
+ if (features.tailwind) {
214
+ await fs.writeFile(path.join(clientDir, TAILWIND_ENTRY), TAILWIND_CSS, 'utf8');
215
+ }
216
+ const toilPath = path.join(clientDir, 'toil.tsx');
217
+ await fs.writeFile(toilPath, setStyleImports(await fs.readFile(toilPath, 'utf8'), features), 'utf8');
218
+ }
129
219
  async function writeFiles(dir, files) {
130
220
  for (const [rel, contents] of Object.entries(files)) {
131
221
  const full = path.join(dir, rel);
@@ -133,16 +223,6 @@ async function writeFiles(dir, files) {
133
223
  await fs.writeFile(full, contents, 'utf8');
134
224
  }
135
225
  }
136
- function run(cmd, args, cwd) {
137
- return new Promise((resolve, reject) => {
138
- const onWindows = process.platform === 'win32';
139
- const child = onWindows
140
- ? spawn([cmd, ...args].join(' '), { cwd, stdio: 'ignore', shell: true })
141
- : spawn(cmd, args, { cwd, stdio: 'ignore' });
142
- child.on('error', reject);
143
- child.on('close', (code) => code === 0 ? resolve() : reject(new Error(`${cmd} exited with code ${String(code)}`)));
144
- });
145
- }
146
226
  export async function runCreate(opts) {
147
227
  intro(accent(' toiljs create '));
148
228
  let name = opts.name;
@@ -169,7 +249,11 @@ export async function runCreate(opts) {
169
249
  cancel(valid);
170
250
  process.exit(1);
171
251
  }
172
- const targetDir = path.resolve(opts.cwd, name);
252
+ const targetDir = resolveProjectDir(opts.cwd, name);
253
+ if (targetDir === null) {
254
+ cancel('Project name must stay inside the current directory (no "..", no absolute paths).');
255
+ process.exit(1);
256
+ }
173
257
  const rel = path.relative(opts.cwd, targetDir) || '.';
174
258
  if (!(await isEmptyDir(targetDir))) {
175
259
  if (opts.yes) {
@@ -189,16 +273,50 @@ export async function runCreate(opts) {
189
273
  let template = opts.template ?? 'app';
190
274
  if (!opts.template && !opts.yes) {
191
275
  const templateOptions = [
192
- { value: 'app', label: 'App', hint: 'layout + home/about + a dynamic /blog/[id] route' },
276
+ { value: 'app', label: 'App', hint: 'the full ToilJS starter landing page, layout, styles, demo routes' },
193
277
  { value: 'minimal', label: 'Minimal', hint: 'just a layout and a home route' },
194
278
  ];
195
279
  const choice = await select({ message: 'Which template?', options: templateOptions, initialValue: 'app' });
196
280
  bail(choice);
197
281
  template = choice === 'minimal' ? 'minimal' : 'app';
198
282
  }
283
+ let preprocessor = opts.preprocessor ?? 'css';
284
+ let tailwind = opts.tailwind ?? false;
285
+ if (!opts.yes) {
286
+ if (opts.preprocessor === undefined) {
287
+ const choice = await select({
288
+ message: 'Styling',
289
+ options: PREPROCESSORS.map((value) => ({ value, label: PREPROCESSOR_LABEL[value] })),
290
+ initialValue: 'css',
291
+ });
292
+ bail(choice);
293
+ preprocessor = choice;
294
+ }
295
+ if (opts.tailwind === undefined) {
296
+ const tw = await confirm({ message: 'Add Tailwind CSS?', initialValue: false });
297
+ bail(tw);
298
+ tailwind = tw;
299
+ }
300
+ }
301
+ const features = { preprocessor, tailwind };
302
+ let aiTools = opts.ai === false ? [] : [...AI_HELPER_IDS];
303
+ if (opts.ai === undefined && !opts.yes) {
304
+ const picked = await multiselect({
305
+ message: 'AI assistant files (read by Claude, Cursor, Codex, Copilot)',
306
+ options: AI_HELPERS.map((h) => ({ value: h.id, label: h.label })),
307
+ initialValues: [...AI_HELPER_IDS],
308
+ required: false,
309
+ });
310
+ bail(picked);
311
+ aiTools = picked;
312
+ }
199
313
  let initGit = opts.git ?? false;
200
314
  let install = opts.install ?? false;
201
315
  const pm = opts.pm ?? 'npm';
316
+ if (!isPackageManager(pm)) {
317
+ cancel(`Unsupported package manager: ${pm} (use npm, pnpm, yarn, or bun).`);
318
+ process.exit(1);
319
+ }
202
320
  if (!opts.yes) {
203
321
  if (opts.git === undefined) {
204
322
  const g = await confirm({ message: 'Initialize a git repository?', initialValue: true });
@@ -213,7 +331,14 @@ export async function runCreate(opts) {
213
331
  }
214
332
  const s = spinner();
215
333
  s.start('Scaffolding project');
216
- await writeFiles(targetDir, scaffold(name, template));
334
+ await writeFiles(targetDir, scaffold(name, template, features, aiTools));
335
+ if (template === 'app') {
336
+ await fs.cp(templateDir('app'), targetDir, { recursive: true });
337
+ const indexHtml = path.join(targetDir, 'client', 'public', 'index.html');
338
+ const html = await fs.readFile(indexHtml, 'utf8');
339
+ await fs.writeFile(indexHtml, html.replace(/<title>[^<]*<\/title>/, `<title>${path.basename(name)}</title>`));
340
+ await applyStyling(path.join(targetDir, 'client'), features);
341
+ }
217
342
  s.stop(`Scaffolded ${pc.cyan(rel)}`);
218
343
  if (initGit) {
219
344
  const g = spinner();
@@ -0,0 +1,23 @@
1
+ export type Preprocessor = 'css' | 'sass' | 'less' | 'stylus';
2
+ export interface StyleFeatures {
3
+ readonly preprocessor: Preprocessor;
4
+ readonly tailwind: boolean;
5
+ }
6
+ export declare const PREPROCESSORS: readonly Preprocessor[];
7
+ export declare const STYLE_EXT: Record<Preprocessor, string>;
8
+ export declare const PREPROCESSOR_PKG: Record<Preprocessor, string | null>;
9
+ export declare const TAILWIND_PKGS: readonly string[];
10
+ export declare const PKG_VERSION: Record<string, string>;
11
+ export declare const TAILWIND_ENTRY = "styles/tailwind.css";
12
+ export declare const TAILWIND_CSS = "@import 'tailwindcss';\n";
13
+ export declare function styleEntry(p: Preprocessor): string;
14
+ export declare function preprocessorForExt(ext: string): Preprocessor | null;
15
+ export declare function requiredPackages(f: StyleFeatures): string[];
16
+ export declare function packageDiff(from: StyleFeatures, to: StyleFeatures): {
17
+ add: string[];
18
+ remove: string[];
19
+ };
20
+ export declare function styleImportLines(f: StyleFeatures): string[];
21
+ export declare function setStyleImports(source: string, f: StyleFeatures): string;
22
+ export declare function detectPreprocessor(deps: Record<string, string>): Preprocessor;
23
+ export declare function detectTailwind(deps: Record<string, string>): boolean;
@@ -0,0 +1,85 @@
1
+ export const PREPROCESSORS = ['css', 'sass', 'less', 'stylus'];
2
+ export const STYLE_EXT = {
3
+ css: 'css',
4
+ sass: 'scss',
5
+ less: 'less',
6
+ stylus: 'styl',
7
+ };
8
+ export const PREPROCESSOR_PKG = {
9
+ css: null,
10
+ sass: 'sass',
11
+ less: 'less',
12
+ stylus: 'stylus',
13
+ };
14
+ export const TAILWIND_PKGS = ['tailwindcss', '@tailwindcss/vite'];
15
+ export const PKG_VERSION = {
16
+ sass: '^1.83.0',
17
+ less: '^4.2.1',
18
+ stylus: '^0.64.0',
19
+ tailwindcss: '^4.0.0',
20
+ '@tailwindcss/vite': '^4.0.0',
21
+ };
22
+ export const TAILWIND_ENTRY = 'styles/tailwind.css';
23
+ export const TAILWIND_CSS = `@import 'tailwindcss';\n`;
24
+ export function styleEntry(p) {
25
+ return `styles/main.${STYLE_EXT[p]}`;
26
+ }
27
+ export function preprocessorForExt(ext) {
28
+ const e = ext.replace(/^\./, '');
29
+ if (e === 'sass')
30
+ return 'sass';
31
+ return PREPROCESSORS.find((p) => STYLE_EXT[p] === e) ?? null;
32
+ }
33
+ export function requiredPackages(f) {
34
+ const pkgs = [];
35
+ const pp = PREPROCESSOR_PKG[f.preprocessor];
36
+ if (pp)
37
+ pkgs.push(pp);
38
+ if (f.tailwind)
39
+ pkgs.push(...TAILWIND_PKGS);
40
+ return pkgs;
41
+ }
42
+ export function packageDiff(from, to) {
43
+ const want = new Set(requiredPackages(to));
44
+ const had = new Set(requiredPackages(from));
45
+ return {
46
+ add: [...want].filter((p) => !had.has(p)),
47
+ remove: [...had].filter((p) => !want.has(p)),
48
+ };
49
+ }
50
+ export function styleImportLines(f) {
51
+ const lines = [];
52
+ if (f.tailwind)
53
+ lines.push(`import './${TAILWIND_ENTRY}';`);
54
+ lines.push(`import './${styleEntry(f.preprocessor)}';`);
55
+ return lines;
56
+ }
57
+ export function setStyleImports(source, f) {
58
+ const stripped = source.replace(/^[ \t]*import\s+['"]\.\/styles\/[^'"]+['"];?[ \t]*\r?\n/gm, '');
59
+ const block = styleImportLines(f).join('\n') + '\n';
60
+ const lines = stripped.split('\n');
61
+ const routesIdx = lines.findIndex((l) => /from\s+['"]toiljs\/routes['"]/.test(l));
62
+ let insertAt;
63
+ if (routesIdx !== -1) {
64
+ insertAt = routesIdx + 1;
65
+ }
66
+ else {
67
+ const lastImport = lines.reduce((acc, l, i) => (/^\s*import\s/.test(l) ? i : acc), -1);
68
+ insertAt = lastImport + 1;
69
+ }
70
+ const head = lines.slice(0, insertAt).join('\n');
71
+ const tail = lines.slice(insertAt).join('\n');
72
+ return `${head}\n\n${block}\n${tail}`.replace(/\n{3,}/g, '\n\n');
73
+ }
74
+ export function detectPreprocessor(deps) {
75
+ if ('sass' in deps)
76
+ return 'sass';
77
+ if ('less' in deps)
78
+ return 'less';
79
+ if ('stylus' in deps)
80
+ return 'stylus';
81
+ return 'css';
82
+ }
83
+ export function detectTailwind(deps) {
84
+ return '@tailwindcss/vite' in deps || 'tailwindcss' in deps;
85
+ }
@@ -1,6 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import { build, dev, start } from 'toiljs/compiler';
3
+ import { runConfigure } from './configure.js';
3
4
  import { runCreate } from './create.js';
5
+ import { PREPROCESSORS } from './features.js';
4
6
  import { accent, banner, bold, danger, dim, success, version } from './ui.js';
5
7
  function parseArgs(argv) {
6
8
  const flags = {};
@@ -10,9 +12,12 @@ function parseArgs(argv) {
10
12
  case '--root':
11
13
  flags.root = argv[++i];
12
14
  break;
13
- case '--port':
14
- flags.port = Number(argv[++i]);
15
+ case '--port': {
16
+ const port = Number(argv[++i]);
17
+ if (!Number.isNaN(port))
18
+ flags.port = port;
15
19
  break;
20
+ }
16
21
  case '--template':
17
22
  case '-t': {
18
23
  const t = argv[++i];
@@ -23,6 +28,24 @@ function parseArgs(argv) {
23
28
  case '--pm':
24
29
  flags.pm = argv[++i];
25
30
  break;
31
+ case '--style': {
32
+ const s = argv[++i];
33
+ if (PREPROCESSORS.includes(s))
34
+ flags.preprocessor = s;
35
+ break;
36
+ }
37
+ case '--tailwind':
38
+ flags.tailwind = true;
39
+ break;
40
+ case '--no-tailwind':
41
+ flags.tailwind = false;
42
+ break;
43
+ case '--ai':
44
+ flags.ai = true;
45
+ break;
46
+ case '--no-ai':
47
+ flags.ai = false;
48
+ break;
26
49
  case '--install':
27
50
  flags.install = true;
28
51
  break;
@@ -53,6 +76,7 @@ function printHelp() {
53
76
  '',
54
77
  bold('Commands'),
55
78
  cmd('create [name]', 'scaffold a new toiljs app'),
79
+ cmd('configure', 'toggle styling features (Sass/Less/Stylus, Tailwind)'),
56
80
  cmd('dev', 'start the dev server with HMR'),
57
81
  cmd('build', 'build the optimized production bundle'),
58
82
  cmd('start', 'self-host the built app (hyper-express / uWS)'),
@@ -61,6 +85,9 @@ function printHelp() {
61
85
  cmd('--root <dir>', 'project root (default: current directory)'),
62
86
  cmd('--port <n>', 'dev server port'),
63
87
  cmd('-t, --template', 'create: app | minimal'),
88
+ cmd('--style <name>', 'create/configure: css | sass | less | stylus'),
89
+ cmd('--tailwind', 'create/configure: enable Tailwind (--no-tailwind to remove)'),
90
+ cmd('--no-ai', 'create: skip AI assistant files (CLAUDE.md, etc.)'),
64
91
  cmd('-y, --yes', 'create: accept defaults (non-interactive)'),
65
92
  cmd('--no-install', "create: don't install dependencies"),
66
93
  cmd('-v, --version', 'print the toiljs version'),
@@ -80,6 +107,9 @@ async function main() {
80
107
  await runCreate({
81
108
  name: flags.name,
82
109
  template: flags.template,
110
+ preprocessor: flags.preprocessor,
111
+ tailwind: flags.tailwind,
112
+ ai: flags.ai,
83
113
  install: flags.install,
84
114
  git: flags.git,
85
115
  pm: flags.pm,
@@ -87,6 +117,16 @@ async function main() {
87
117
  cwd: process.cwd(),
88
118
  });
89
119
  break;
120
+ case 'configure':
121
+ banner();
122
+ await runConfigure({
123
+ root: flags.root,
124
+ preprocessor: flags.preprocessor,
125
+ tailwind: flags.tailwind,
126
+ install: flags.install,
127
+ cwd: process.cwd(),
128
+ });
129
+ break;
90
130
  case 'dev':
91
131
  banner();
92
132
  process.stdout.write(dim(' starting dev server…') + '\n\n');
@@ -0,0 +1 @@
1
+ export declare function run(cmd: string, args: string[], cwd: string): Promise<void>;
@@ -0,0 +1,11 @@
1
+ import { spawn } from 'node:child_process';
2
+ export function run(cmd, args, cwd) {
3
+ return new Promise((resolve, reject) => {
4
+ const onWindows = process.platform === 'win32';
5
+ const child = onWindows
6
+ ? spawn([cmd, ...args].join(' '), { cwd, stdio: 'ignore', shell: true })
7
+ : spawn(cmd, args, { cwd, stdio: 'ignore' });
8
+ child.on('error', reject);
9
+ child.on('close', (code) => code === 0 ? resolve() : reject(new Error(`${cmd} exited with code ${String(code)}`)));
10
+ });
11
+ }
package/build/cli/ui.js CHANGED
@@ -63,8 +63,7 @@ export function version() {
63
63
  if (match && match[1])
64
64
  return match[1];
65
65
  }
66
- catch {
67
- }
66
+ catch { }
68
67
  return '0.0.0';
69
68
  }
70
69
  export function banner() {
@@ -0,0 +1,4 @@
1
+ export declare const PACKAGE_MANAGERS: string[];
2
+ export declare function isValidName(name: string): true | string;
3
+ export declare function resolveProjectDir(cwd: string, name: string): string | null;
4
+ export declare function isPackageManager(pm: string): boolean;
@@ -0,0 +1,19 @@
1
+ import path from 'node:path';
2
+ export const PACKAGE_MANAGERS = ['npm', 'pnpm', 'yarn', 'bun'];
3
+ export function isValidName(name) {
4
+ if (!name.trim())
5
+ return 'Please enter a project name.';
6
+ if (!/^[a-z0-9._@/-]+$/i.test(name))
7
+ return 'Use letters, numbers, dashes, dots or slashes.';
8
+ return true;
9
+ }
10
+ export function resolveProjectDir(cwd, name) {
11
+ const target = path.resolve(cwd, name);
12
+ const rel = path.relative(cwd, target);
13
+ if (rel.startsWith('..') || path.isAbsolute(rel))
14
+ return null;
15
+ return target;
16
+ }
17
+ export function isPackageManager(pm) {
18
+ return PACKAGE_MANAGERS.includes(pm);
19
+ }