toiljs 0.0.4 → 0.0.5
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.
- package/.idea/prettier.xml +1 -0
- package/as-pect.config.js +1 -1
- package/build/backend/.tsbuildinfo +1 -1
- package/build/backend/index.js +1 -2
- package/build/cli/.tsbuildinfo +1 -1
- package/build/cli/configure.d.ts +15 -0
- package/build/cli/configure.js +201 -0
- package/build/cli/create.d.ts +4 -0
- package/build/cli/create.js +168 -57
- package/build/cli/features.d.ts +23 -0
- package/build/cli/features.js +85 -0
- package/build/cli/index.js +42 -2
- package/build/cli/proc.d.ts +1 -0
- package/build/cli/proc.js +11 -0
- package/build/cli/ui.js +1 -2
- package/build/cli/validate.d.ts +4 -0
- package/build/cli/validate.js +19 -0
- package/build/client/.tsbuildinfo +1 -1
- package/build/client/Link.d.ts +8 -0
- package/build/client/Link.js +44 -0
- package/build/client/NavLink.d.ts +14 -0
- package/build/client/NavLink.js +37 -0
- package/build/client/Router.d.ts +7 -0
- package/build/client/Router.js +55 -0
- package/build/client/error-boundary.d.ts +16 -0
- package/build/client/error-boundary.js +19 -0
- package/build/client/head.d.ts +26 -0
- package/build/client/head.js +87 -0
- package/build/client/hooks.d.ts +17 -0
- package/build/client/hooks.js +48 -0
- package/build/client/index.d.ts +14 -2
- package/build/client/index.js +8 -1
- package/build/client/lazy.d.ts +16 -0
- package/build/client/lazy.js +53 -0
- package/build/client/match.js +7 -0
- package/build/client/mount.d.ts +2 -0
- package/build/client/mount.js +13 -0
- package/build/client/navigation.d.ts +13 -0
- package/build/client/navigation.js +97 -0
- package/build/client/params-context.d.ts +2 -0
- package/build/client/params-context.js +2 -0
- package/build/client/prefetch.d.ts +11 -0
- package/build/client/prefetch.js +100 -0
- package/build/client/scroll.d.ts +8 -0
- package/build/client/scroll.js +36 -0
- package/build/client/types.d.ts +27 -0
- package/build/client/types.js +1 -0
- package/build/compiler/.tsbuildinfo +1 -1
- package/build/compiler/config.d.ts +2 -0
- package/build/compiler/config.js +4 -1
- package/build/compiler/docs.d.ts +10 -0
- package/build/compiler/docs.js +59 -0
- package/build/compiler/generate.js +134 -16
- package/build/compiler/index.d.ts +4 -2
- package/build/compiler/index.js +4 -3
- package/build/compiler/plugin.js +2 -1
- package/build/compiler/routes.js +5 -1
- package/build/compiler/vite.d.ts +1 -1
- package/build/compiler/vite.js +17 -1
- package/build/io/.tsbuildinfo +1 -1
- package/build/io/BinaryWriter.js +2 -2
- package/eslint.config.js +1 -1
- package/examples/basic/.toil/docs/cli.md +3 -0
- package/examples/basic/.toil/docs/client.md +3 -0
- package/examples/basic/.toil/docs/index.md +3 -0
- package/examples/basic/.toil/docs/routing.md +3 -0
- package/examples/basic/.toil/docs/server.md +3 -0
- package/examples/basic/.toil/docs/styling.md +3 -0
- package/examples/basic/.toil/entry.tsx +3 -8
- package/examples/basic/.toil/globals.ts +6 -0
- package/examples/basic/.toil/index.html +16 -12
- package/examples/basic/.toil/public/images/.gitkeep +1 -0
- package/examples/basic/.toil/public/images/logo.svg +37 -0
- package/examples/basic/.toil/public/robots.txt +2 -0
- package/examples/basic/.toil/routes.ts +9 -7
- package/examples/basic/build/client/assets/404-Bq0jNTUo.js +1 -0
- package/examples/basic/build/client/assets/_...slug_-CXKf6qnB.js +1 -0
- package/examples/basic/build/client/assets/_id_-BadAyQnb.js +1 -0
- package/examples/basic/build/client/assets/about-BOhoEcEO.js +1 -0
- package/examples/basic/build/client/assets/get-started-BIXpcjkT.js +9 -0
- package/examples/basic/build/client/assets/index-BmqcTaBB.js +1 -0
- package/examples/basic/build/client/assets/io-DEVjjaJj.js +1 -0
- package/examples/basic/build/client/assets/layout-DJegirdz.js +1 -0
- package/examples/basic/build/client/assets/react-DEQrz1q7.js +9 -0
- package/examples/basic/build/client/assets/rolldown-runtime-KL5VtC6j.js +1 -0
- package/examples/basic/build/client/assets/routes-BYWn6TxK.js +1 -0
- package/examples/basic/build/client/css/style.css +2 -0
- package/examples/basic/build/client/images/.gitkeep +1 -0
- package/examples/basic/build/client/images/logo.svg +37 -0
- package/examples/basic/build/client/index.html +17 -0
- package/examples/basic/build/client/robots.txt +2 -0
- package/examples/basic/client/404.tsx +2 -5
- package/examples/basic/client/components/.gitkeep +1 -0
- package/examples/basic/client/components/Footer.tsx +8 -0
- package/examples/basic/client/layout.tsx +39 -26
- package/examples/basic/client/public/images/.gitkeep +1 -0
- package/examples/basic/client/public/images/logo.svg +37 -0
- package/examples/basic/client/public/index.html +15 -0
- package/examples/basic/client/public/robots.txt +2 -0
- package/examples/basic/client/routes/about.tsx +1 -3
- package/examples/basic/client/routes/blog/[id].tsx +2 -4
- package/examples/basic/client/routes/docs/[...slug].tsx +3 -6
- package/examples/basic/client/routes/get-started.tsx +84 -0
- package/examples/basic/client/routes/index.tsx +74 -7
- package/examples/basic/client/routes/io.tsx +3 -7
- package/examples/basic/client/styles/main.css +461 -0
- package/examples/basic/client/toil.tsx +7 -0
- package/examples/basic/node_modules/.bin/toilinit +16 -0
- package/examples/basic/node_modules/.bin/toilinit.cmd +17 -0
- package/examples/basic/node_modules/.bin/toilinit.ps1 +28 -0
- package/examples/basic/node_modules/.bin/toilscript +16 -0
- package/examples/basic/node_modules/.bin/toilscript.cmd +17 -0
- package/examples/basic/node_modules/.bin/toilscript.ps1 +28 -0
- package/examples/basic/node_modules/.bin/wasm-as +16 -0
- package/examples/basic/node_modules/.bin/wasm-as.cmd +17 -0
- package/examples/basic/node_modules/.bin/wasm-as.ps1 +28 -0
- package/examples/basic/node_modules/.bin/wasm-ctor-eval +16 -0
- package/examples/basic/node_modules/.bin/wasm-ctor-eval.cmd +17 -0
- package/examples/basic/node_modules/.bin/wasm-ctor-eval.ps1 +28 -0
- package/examples/basic/node_modules/.bin/wasm-dis +16 -0
- package/examples/basic/node_modules/.bin/wasm-dis.cmd +17 -0
- package/examples/basic/node_modules/.bin/wasm-dis.ps1 +28 -0
- package/examples/basic/node_modules/.bin/wasm-merge +16 -0
- package/examples/basic/node_modules/.bin/wasm-merge.cmd +17 -0
- package/examples/basic/node_modules/.bin/wasm-merge.ps1 +28 -0
- package/examples/basic/node_modules/.bin/wasm-metadce +16 -0
- package/examples/basic/node_modules/.bin/wasm-metadce.cmd +17 -0
- package/examples/basic/node_modules/.bin/wasm-metadce.ps1 +28 -0
- package/examples/basic/node_modules/.bin/wasm-opt +16 -0
- package/examples/basic/node_modules/.bin/wasm-opt.cmd +17 -0
- package/examples/basic/node_modules/.bin/wasm-opt.ps1 +28 -0
- package/examples/basic/node_modules/.bin/wasm-reduce +16 -0
- package/examples/basic/node_modules/.bin/wasm-reduce.cmd +17 -0
- package/examples/basic/node_modules/.bin/wasm-reduce.ps1 +28 -0
- package/examples/basic/node_modules/.bin/wasm-shell +16 -0
- package/examples/basic/node_modules/.bin/wasm-shell.cmd +17 -0
- package/examples/basic/node_modules/.bin/wasm-shell.ps1 +28 -0
- package/examples/basic/node_modules/.bin/wasm2js +16 -0
- package/examples/basic/node_modules/.bin/wasm2js.cmd +17 -0
- package/examples/basic/node_modules/.bin/wasm2js.ps1 +28 -0
- package/examples/basic/node_modules/.package-lock.json +49 -1
- package/examples/basic/node_modules/.vite/deps/_metadata.json +9 -9
- package/examples/basic/node_modules/binaryen/LICENSE +201 -0
- package/examples/basic/node_modules/binaryen/README.md +1362 -0
- package/examples/basic/node_modules/binaryen/bin/package.json +3 -0
- package/examples/basic/node_modules/binaryen/bin/wasm-as +0 -0
- package/examples/basic/node_modules/binaryen/bin/wasm-ctor-eval +0 -0
- package/examples/basic/node_modules/binaryen/bin/wasm-dis +0 -0
- package/examples/basic/node_modules/binaryen/bin/wasm-merge +0 -0
- package/examples/basic/node_modules/binaryen/bin/wasm-metadce +0 -0
- package/examples/basic/node_modules/binaryen/bin/wasm-opt +0 -0
- package/examples/basic/node_modules/binaryen/bin/wasm-reduce +0 -0
- package/examples/basic/node_modules/binaryen/bin/wasm-shell +0 -0
- package/examples/basic/node_modules/binaryen/bin/wasm2js +0 -0
- package/examples/basic/node_modules/binaryen/index.d.ts +2371 -0
- package/examples/basic/node_modules/binaryen/index.js +30552 -0
- package/examples/basic/node_modules/binaryen/package.json +50 -0
- package/examples/basic/node_modules/long/LICENSE +202 -0
- package/examples/basic/node_modules/long/README.md +286 -0
- package/examples/basic/node_modules/long/index.d.ts +2 -0
- package/examples/basic/node_modules/long/index.js +1581 -0
- package/examples/basic/node_modules/long/package.json +58 -0
- package/examples/basic/node_modules/long/types.d.ts +474 -0
- package/examples/basic/node_modules/long/umd/index.d.ts +3 -0
- package/examples/basic/node_modules/long/umd/index.js +1622 -0
- package/examples/basic/node_modules/long/umd/package.json +3 -0
- package/examples/basic/node_modules/long/umd/types.d.ts +474 -0
- package/examples/basic/node_modules/toilscript/LICENSE +201 -0
- package/examples/basic/node_modules/toilscript/NOTICE +94 -0
- package/examples/basic/node_modules/toilscript/README.md +66 -0
- package/examples/basic/node_modules/toilscript/bin/toilinit.js +468 -0
- package/examples/basic/node_modules/toilscript/bin/toilscript.js +35 -0
- package/examples/basic/node_modules/toilscript/dist/cli.d.ts +4 -0
- package/examples/basic/node_modules/toilscript/dist/cli.generated.d.ts +10027 -0
- package/examples/basic/node_modules/toilscript/dist/cli.js +24474 -0
- package/examples/basic/node_modules/toilscript/dist/cli.js.map +7 -0
- package/examples/basic/node_modules/toilscript/dist/importmap.json +9 -0
- package/examples/basic/node_modules/toilscript/dist/toilscript.d.ts +4 -0
- package/examples/basic/node_modules/toilscript/dist/toilscript.generated.d.ts +11242 -0
- package/examples/basic/node_modules/toilscript/dist/toilscript.js +337 -0
- package/examples/basic/node_modules/toilscript/dist/toilscript.js.map +7 -0
- package/examples/basic/node_modules/toilscript/dist/transform.cjs +1 -0
- package/examples/basic/node_modules/toilscript/dist/transform.d.ts +1 -0
- package/examples/basic/node_modules/toilscript/dist/transform.js +1 -0
- package/examples/basic/node_modules/toilscript/dist/web.js +22 -0
- package/examples/basic/node_modules/toilscript/lib/binaryen.d.ts +2 -0
- package/examples/basic/node_modules/toilscript/lib/binaryen.js +2 -0
- package/examples/basic/node_modules/toilscript/package.json +115 -0
- package/examples/basic/node_modules/toilscript/std/README.md +6 -0
- package/examples/basic/node_modules/toilscript/std/assembly/array.ts +550 -0
- package/examples/basic/node_modules/toilscript/std/assembly/arraybuffer.ts +77 -0
- package/examples/basic/node_modules/toilscript/std/assembly/atomics.ts +127 -0
- package/examples/basic/node_modules/toilscript/std/assembly/bindings/asyncify.ts +16 -0
- package/examples/basic/node_modules/toilscript/std/assembly/bindings/dom.ts +291 -0
- package/examples/basic/node_modules/toilscript/std/assembly/bindings/node.ts +6 -0
- package/examples/basic/node_modules/toilscript/std/assembly/bitflags.ts +53 -0
- package/examples/basic/node_modules/toilscript/std/assembly/builtins.ts +2650 -0
- package/examples/basic/node_modules/toilscript/std/assembly/byteslice.ts +177 -0
- package/examples/basic/node_modules/toilscript/std/assembly/compat.ts +2 -0
- package/examples/basic/node_modules/toilscript/std/assembly/console.ts +42 -0
- package/examples/basic/node_modules/toilscript/std/assembly/crypto.ts +9 -0
- package/examples/basic/node_modules/toilscript/std/assembly/dataview.ts +181 -0
- package/examples/basic/node_modules/toilscript/std/assembly/date.ts +375 -0
- package/examples/basic/node_modules/toilscript/std/assembly/diagnostics.ts +11 -0
- package/examples/basic/node_modules/toilscript/std/assembly/encoding.ts +151 -0
- package/examples/basic/node_modules/toilscript/std/assembly/endian.ts +45 -0
- package/examples/basic/node_modules/toilscript/std/assembly/error.ts +44 -0
- package/examples/basic/node_modules/toilscript/std/assembly/fixedarray.ts +173 -0
- package/examples/basic/node_modules/toilscript/std/assembly/fixedmap.ts +326 -0
- package/examples/basic/node_modules/toilscript/std/assembly/fixedset.ts +275 -0
- package/examples/basic/node_modules/toilscript/std/assembly/function.ts +42 -0
- package/examples/basic/node_modules/toilscript/std/assembly/index.d.ts +2892 -0
- package/examples/basic/node_modules/toilscript/std/assembly/iterator.ts +35 -0
- package/examples/basic/node_modules/toilscript/std/assembly/map.ts +269 -0
- package/examples/basic/node_modules/toilscript/std/assembly/math.ts +3289 -0
- package/examples/basic/node_modules/toilscript/std/assembly/memory.ts +123 -0
- package/examples/basic/node_modules/toilscript/std/assembly/number.ts +388 -0
- package/examples/basic/node_modules/toilscript/std/assembly/object.ts +36 -0
- package/examples/basic/node_modules/toilscript/std/assembly/performance.ts +9 -0
- package/examples/basic/node_modules/toilscript/std/assembly/pointer.ts +80 -0
- package/examples/basic/node_modules/toilscript/std/assembly/polyfills.ts +27 -0
- package/examples/basic/node_modules/toilscript/std/assembly/process.ts +50 -0
- package/examples/basic/node_modules/toilscript/std/assembly/reference.ts +48 -0
- package/examples/basic/node_modules/toilscript/std/assembly/regexp.ts +12 -0
- package/examples/basic/node_modules/toilscript/std/assembly/rt/README.md +83 -0
- package/examples/basic/node_modules/toilscript/std/assembly/rt/common.ts +81 -0
- package/examples/basic/node_modules/toilscript/std/assembly/rt/index-incremental.ts +2 -0
- package/examples/basic/node_modules/toilscript/std/assembly/rt/index-memory.ts +1 -0
- package/examples/basic/node_modules/toilscript/std/assembly/rt/index-minimal.ts +2 -0
- package/examples/basic/node_modules/toilscript/std/assembly/rt/index-stub.ts +1 -0
- package/examples/basic/node_modules/toilscript/std/assembly/rt/index.d.ts +37 -0
- package/examples/basic/node_modules/toilscript/std/assembly/rt/itcms.ts +419 -0
- package/examples/basic/node_modules/toilscript/std/assembly/rt/memory-runtime.ts +94 -0
- package/examples/basic/node_modules/toilscript/std/assembly/rt/rtrace.ts +15 -0
- package/examples/basic/node_modules/toilscript/std/assembly/rt/stub.ts +133 -0
- package/examples/basic/node_modules/toilscript/std/assembly/rt/tcms.ts +254 -0
- package/examples/basic/node_modules/toilscript/std/assembly/rt/tlsf.ts +592 -0
- package/examples/basic/node_modules/toilscript/std/assembly/rt.ts +90 -0
- package/examples/basic/node_modules/toilscript/std/assembly/set.ts +225 -0
- package/examples/basic/node_modules/toilscript/std/assembly/shared/feature.ts +68 -0
- package/examples/basic/node_modules/toilscript/std/assembly/shared/runtime.ts +13 -0
- package/examples/basic/node_modules/toilscript/std/assembly/shared/target.ts +11 -0
- package/examples/basic/node_modules/toilscript/std/assembly/shared/tsconfig.json +11 -0
- package/examples/basic/node_modules/toilscript/std/assembly/shared/typeinfo.ts +72 -0
- package/examples/basic/node_modules/toilscript/std/assembly/staticarray.ts +423 -0
- package/examples/basic/node_modules/toilscript/std/assembly/string.ts +850 -0
- package/examples/basic/node_modules/toilscript/std/assembly/symbol.ts +114 -0
- package/examples/basic/node_modules/toilscript/std/assembly/table.ts +16 -0
- package/examples/basic/node_modules/toilscript/std/assembly/toilscript.ts +16 -0
- package/examples/basic/node_modules/toilscript/std/assembly/tsconfig.json +6 -0
- package/examples/basic/node_modules/toilscript/std/assembly/typedarray.ts +1954 -0
- package/examples/basic/node_modules/toilscript/std/assembly/uri.ts +17 -0
- package/examples/basic/node_modules/toilscript/std/assembly/util/bytes.ts +107 -0
- package/examples/basic/node_modules/toilscript/std/assembly/util/casemap.ts +497 -0
- package/examples/basic/node_modules/toilscript/std/assembly/util/error.ts +58 -0
- package/examples/basic/node_modules/toilscript/std/assembly/util/hash.ts +117 -0
- package/examples/basic/node_modules/toilscript/std/assembly/util/math.ts +1922 -0
- package/examples/basic/node_modules/toilscript/std/assembly/util/memory.ts +290 -0
- package/examples/basic/node_modules/toilscript/std/assembly/util/number.ts +873 -0
- package/examples/basic/node_modules/toilscript/std/assembly/util/sort.ts +313 -0
- package/examples/basic/node_modules/toilscript/std/assembly/util/string.ts +1202 -0
- package/examples/basic/node_modules/toilscript/std/assembly/util/uri.ts +275 -0
- package/examples/basic/node_modules/toilscript/std/assembly/vector.ts +4 -0
- package/examples/basic/node_modules/toilscript/std/assembly.json +16 -0
- package/examples/basic/node_modules/toilscript/std/portable/index.d.ts +461 -0
- package/examples/basic/node_modules/toilscript/std/portable/index.js +416 -0
- package/examples/basic/node_modules/toilscript/std/portable.json +11 -0
- package/examples/basic/node_modules/toilscript/std/types/assembly/index.d.ts +1 -0
- package/examples/basic/node_modules/toilscript/std/types/assembly/package.json +3 -0
- package/examples/basic/node_modules/toilscript/std/types/portable/index.d.ts +1 -0
- package/examples/basic/node_modules/toilscript/std/types/portable/package.json +3 -0
- package/examples/basic/node_modules/toilscript/tsconfig-base.json +13 -0
- package/examples/basic/node_modules/toilscript/util/README.md +23 -0
- package/examples/basic/node_modules/toilscript/util/browser/fs.js +1 -0
- package/examples/basic/node_modules/toilscript/util/browser/module.js +5 -0
- package/examples/basic/node_modules/toilscript/util/browser/path.js +520 -0
- package/examples/basic/node_modules/toilscript/util/browser/process.js +59 -0
- package/examples/basic/node_modules/toilscript/util/browser/url.js +23 -0
- package/examples/basic/node_modules/toilscript/util/cpu.d.ts +9 -0
- package/examples/basic/node_modules/toilscript/util/cpu.js +42 -0
- package/examples/basic/node_modules/toilscript/util/find.d.ts +6 -0
- package/examples/basic/node_modules/toilscript/util/find.js +20 -0
- package/examples/basic/node_modules/toilscript/util/node.d.ts +21 -0
- package/examples/basic/node_modules/toilscript/util/node.js +34 -0
- package/examples/basic/node_modules/toilscript/util/options.d.ts +70 -0
- package/examples/basic/node_modules/toilscript/util/options.js +262 -0
- package/examples/basic/node_modules/toilscript/util/terminal.d.ts +52 -0
- package/examples/basic/node_modules/toilscript/util/terminal.js +35 -0
- package/examples/basic/node_modules/toilscript/util/text.d.ts +26 -0
- package/examples/basic/node_modules/toilscript/util/text.js +114 -0
- package/examples/basic/node_modules/toilscript/util/tsconfig.json +9 -0
- package/examples/basic/node_modules/toilscript/util/web.d.ts +11 -0
- package/examples/basic/node_modules/toilscript/util/web.js +33 -0
- package/examples/basic/package-lock.json +50 -1
- package/examples/basic/package.json +5 -2
- package/examples/basic/server/index.ts +3 -0
- package/examples/basic/server/main.ts +6 -0
- package/examples/basic/server/tsconfig.json +7 -0
- package/examples/basic/toil-env.d.ts +20 -1
- package/examples/basic/toil.config.ts +2 -5
- package/examples/basic/toilconfig.json +30 -0
- package/package.json +1 -1
- package/presets/eslint.js +2 -7
- package/presets/no-uint8array-tostring.js +4 -5
- package/presets/prettier.json +8 -1
- package/src/backend/index.ts +11 -18
- package/src/cli/configure.ts +272 -0
- package/src/cli/create.ts +227 -69
- package/src/cli/features.ts +128 -0
- package/src/cli/index.ts +44 -3
- package/src/cli/proc.ts +20 -0
- package/src/cli/ui.ts +4 -6
- package/src/cli/validate.ts +31 -0
- package/src/client/Link.tsx +99 -0
- package/src/client/NavLink.tsx +86 -0
- package/src/client/Router.tsx +95 -0
- package/src/client/error-boundary.tsx +43 -0
- package/src/client/head.ts +140 -0
- package/src/client/hooks.ts +115 -0
- package/src/client/index.ts +35 -5
- package/src/client/lazy.ts +93 -0
- package/src/client/match.ts +11 -3
- package/src/client/mount.tsx +28 -0
- package/src/client/navigation.ts +142 -0
- package/src/client/params-context.ts +10 -0
- package/src/client/prefetch.ts +130 -0
- package/src/client/scroll.ts +53 -0
- package/src/client/types.ts +36 -0
- package/src/compiler/config.ts +15 -8
- package/src/compiler/docs.ts +87 -0
- package/src/compiler/generate.ts +164 -23
- package/src/compiler/index.ts +6 -4
- package/src/compiler/plugin.ts +3 -1
- package/src/compiler/routes.ts +13 -7
- package/src/compiler/vite.ts +28 -5
- package/src/io/BinaryReader.ts +1 -5
- package/src/io/BinaryWriter.ts +3 -3
- package/src/server/index.ts +3 -4
- package/src/server/tsconfig.json +4 -0
- package/test/configure.test.ts +90 -0
- package/test/features.test.ts +111 -0
- package/test/head.test.ts +35 -0
- package/test/io.test.ts +8 -0
- package/test/navlink.test.ts +28 -0
- package/test/routes.test.ts +15 -0
- package/test/validate.test.ts +42 -0
- package/vitest.config.ts +1 -1
- package/examples/basic/dist/assets/404-D1bS2aH_.js +0 -1
- package/examples/basic/dist/assets/_...slug_-wR3shlWn.js +0 -1
- package/examples/basic/dist/assets/_id_-EWYvHfi2.js +0 -1
- package/examples/basic/dist/assets/about-Ddvj1tjF.js +0 -1
- package/examples/basic/dist/assets/index-CdG0me90.js +0 -1
- package/examples/basic/dist/assets/io-CODNJU57.js +0 -1
- package/examples/basic/dist/assets/layout-C15ZTPYI.js +0 -1
- package/examples/basic/dist/assets/react-JbAfoxYe.js +0 -9
- package/examples/basic/dist/assets/rolldown-runtime-1VNLd2iN.js +0 -1
- package/examples/basic/dist/assets/routes-GoydenoY.js +0 -1
- package/examples/basic/dist/index.html +0 -12
- package/src/client/runtime.tsx +0 -190
package/src/cli/create.ts
CHANGED
|
@@ -3,18 +3,61 @@
|
|
|
3
3
|
* app to the enforced toiljs presets (tsconfig / eslint / prettier) and file-based routing.
|
|
4
4
|
* Supports a non-interactive path via flags (`--yes`, `--template`, …) for scripting/CI.
|
|
5
5
|
*/
|
|
6
|
-
import { spawn } from 'node:child_process';
|
|
7
6
|
import fs from 'node:fs/promises';
|
|
8
7
|
import path from 'node:path';
|
|
9
8
|
|
|
10
|
-
import {
|
|
11
|
-
|
|
9
|
+
import {
|
|
10
|
+
intro,
|
|
11
|
+
outro,
|
|
12
|
+
text,
|
|
13
|
+
select,
|
|
14
|
+
multiselect,
|
|
15
|
+
confirm,
|
|
16
|
+
isCancel,
|
|
17
|
+
cancel,
|
|
18
|
+
spinner,
|
|
19
|
+
note,
|
|
20
|
+
} from '@clack/prompts';
|
|
21
|
+
import { AI_HELPERS, AI_HELPER_IDS, aiHelperFiles, TOIL_DOCS, TOIL_ENV_DTS } from 'toiljs/compiler';
|
|
12
22
|
import pc from 'picocolors';
|
|
13
23
|
|
|
24
|
+
import {
|
|
25
|
+
PKG_VERSION,
|
|
26
|
+
PREPROCESSORS,
|
|
27
|
+
requiredPackages,
|
|
28
|
+
styleEntry,
|
|
29
|
+
styleImportLines,
|
|
30
|
+
TAILWIND_CSS,
|
|
31
|
+
TAILWIND_ENTRY,
|
|
32
|
+
type Preprocessor,
|
|
33
|
+
type StyleFeatures,
|
|
34
|
+
} from './features.js';
|
|
35
|
+
import { run } from './proc.js';
|
|
14
36
|
import { accent, dim, version } from './ui.js';
|
|
37
|
+
import { isPackageManager, isValidName, resolveProjectDir } from './validate.js';
|
|
15
38
|
|
|
16
39
|
export type Template = 'app' | 'minimal';
|
|
17
40
|
|
|
41
|
+
/** Human label for each preprocessor in the styling picker. */
|
|
42
|
+
const PREPROCESSOR_LABEL: Record<Preprocessor, string> = {
|
|
43
|
+
css: 'Plain CSS',
|
|
44
|
+
sass: 'Sass (SCSS)',
|
|
45
|
+
less: 'Less',
|
|
46
|
+
stylus: 'Stylus',
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/** Default global stylesheet contents (palette base styles), shared by every preprocessor. */
|
|
50
|
+
const DEFAULT_STYLE_CONTENT =
|
|
51
|
+
':root {\n color-scheme: dark;\n}\n\n' +
|
|
52
|
+
'body {\n margin: 0;\n background: #080d11;\n color: #f5f6fa;\n' +
|
|
53
|
+
' font-family: system-ui, -apple-system, sans-serif;\n line-height: 1.6;\n}\n\n' +
|
|
54
|
+
'a {\n color: #2563ff;\n text-decoration: none;\n}\n\n' +
|
|
55
|
+
'a:hover {\n color: #22e3ab;\n}\n\n' +
|
|
56
|
+
'code {\n background: #11161f;\n color: #22e3ab;\n padding: 0.1rem 0.4rem;\n' +
|
|
57
|
+
' border-radius: 4px;\n font-size: 0.9em;\n}\n\n' +
|
|
58
|
+
'h1 {\n background: linear-gradient(90deg, #2563ff, #7c3aed, #22e3ab);\n' +
|
|
59
|
+
' -webkit-background-clip: text;\n background-clip: text;\n color: transparent;\n}\n';
|
|
60
|
+
|
|
18
61
|
/** A selectable template in the `create` wizard. */
|
|
19
62
|
interface TemplateOption {
|
|
20
63
|
readonly value: Template;
|
|
@@ -25,6 +68,10 @@ interface TemplateOption {
|
|
|
25
68
|
export interface CreateOptions {
|
|
26
69
|
readonly name?: string;
|
|
27
70
|
readonly template?: Template;
|
|
71
|
+
readonly preprocessor?: Preprocessor;
|
|
72
|
+
readonly tailwind?: boolean;
|
|
73
|
+
/** AI assistant files to scaffold: `true` = all, `false` = none, omitted = ask. */
|
|
74
|
+
readonly ai?: boolean;
|
|
28
75
|
readonly install?: boolean;
|
|
29
76
|
readonly git?: boolean;
|
|
30
77
|
readonly pm?: string;
|
|
@@ -40,79 +87,165 @@ function bail<T>(value: T | symbol): asserts value is T {
|
|
|
40
87
|
}
|
|
41
88
|
}
|
|
42
89
|
|
|
43
|
-
function isValidName(name: string): true | string {
|
|
44
|
-
if (!name.trim()) return 'Please enter a project name.';
|
|
45
|
-
if (!/^[a-z0-9._@/-]+$/i.test(name)) return 'Use letters, numbers, dashes, dots or slashes.';
|
|
46
|
-
return true;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
90
|
async function isEmptyDir(dir: string): Promise<boolean> {
|
|
50
91
|
try {
|
|
51
92
|
const entries = await fs.readdir(dir);
|
|
52
93
|
return entries.length === 0;
|
|
53
94
|
} catch {
|
|
54
|
-
return true;
|
|
95
|
+
return true;
|
|
55
96
|
}
|
|
56
97
|
}
|
|
57
98
|
|
|
58
99
|
/** Builds the full file map (relative path → contents) for a scaffolded project. */
|
|
59
|
-
function scaffold(
|
|
100
|
+
function scaffold(
|
|
101
|
+
name: string,
|
|
102
|
+
template: Template,
|
|
103
|
+
features: StyleFeatures,
|
|
104
|
+
aiTools: readonly string[],
|
|
105
|
+
): Record<string, string> {
|
|
60
106
|
const toilVersion = version();
|
|
107
|
+
const devDependencies: Record<string, string> = {
|
|
108
|
+
'@types/react': '^19.2.15',
|
|
109
|
+
'@types/react-dom': '^19.2.3',
|
|
110
|
+
eslint: '^10.2.0',
|
|
111
|
+
prettier: '^3.8.1',
|
|
112
|
+
toilscript: '^0.1.2',
|
|
113
|
+
typescript: '^6.0.3',
|
|
114
|
+
};
|
|
115
|
+
for (const dep of requiredPackages(features).sort()) {
|
|
116
|
+
devDependencies[dep] = PKG_VERSION[dep] ?? 'latest';
|
|
117
|
+
}
|
|
61
118
|
const pkg = {
|
|
62
119
|
name: path.basename(name),
|
|
63
120
|
private: true,
|
|
64
121
|
type: 'module',
|
|
65
122
|
scripts: {
|
|
66
123
|
dev: 'toiljs dev',
|
|
67
|
-
build: 'toiljs build',
|
|
124
|
+
build: 'toiljs build && toilscript --target release',
|
|
125
|
+
'build:client': 'toiljs build',
|
|
126
|
+
'build:server': 'toilscript --target release',
|
|
68
127
|
lint: 'eslint client',
|
|
69
128
|
typecheck: 'tsc --noEmit',
|
|
70
|
-
format: 'prettier --write "client/**/*.{ts,tsx}"',
|
|
129
|
+
format: 'prettier --write "client/**/*.{ts,tsx,css,scss,less}" "client/public/**/*.html"',
|
|
71
130
|
},
|
|
72
131
|
dependencies: {
|
|
73
132
|
toiljs: `^${toilVersion}`,
|
|
74
133
|
react: '^19.2.6',
|
|
75
134
|
'react-dom': '^19.2.6',
|
|
76
135
|
},
|
|
77
|
-
devDependencies
|
|
78
|
-
'@types/react': '^19.2.15',
|
|
79
|
-
'@types/react-dom': '^19.2.3',
|
|
80
|
-
eslint: '^10.2.0',
|
|
81
|
-
prettier: '^3.8.1',
|
|
82
|
-
typescript: '^6.0.3',
|
|
83
|
-
},
|
|
136
|
+
devDependencies,
|
|
84
137
|
};
|
|
85
138
|
|
|
86
139
|
const files: Record<string, string> = {
|
|
87
140
|
'package.json': JSON.stringify(pkg, null, 4) + '\n',
|
|
88
141
|
'toil.config.ts':
|
|
89
142
|
"import { defineConfig } from 'toiljs/compiler';\n\n" +
|
|
90
|
-
'export default defineConfig({
|
|
143
|
+
'export default defineConfig({});\n',
|
|
91
144
|
'tsconfig.json':
|
|
92
145
|
'{\n "extends": "toiljs/tsconfig",\n "include": ["client", "toil-env.d.ts"]\n}\n',
|
|
93
146
|
'eslint.config.js': "import toiljs from 'toiljs/eslint';\n\nexport default toiljs;\n",
|
|
94
147
|
'.prettierrc': '"toiljs/prettier"\n',
|
|
95
|
-
'.gitignore': 'node_modules\
|
|
96
|
-
|
|
148
|
+
'.gitignore': 'node_modules\nbuild\n.toil\ntoil-env.d.ts\n',
|
|
149
|
+
'client/public/index.html':
|
|
150
|
+
'<!doctype html>\n<html lang="en">\n <head>\n' +
|
|
151
|
+
' <meta charset="utf-8" />\n' +
|
|
152
|
+
' <meta name="viewport" content="width=device-width, initial-scale=1" />\n' +
|
|
153
|
+
' <meta name="theme-color" content="#080D11" />\n' +
|
|
154
|
+
' <meta name="description" content="" />\n' +
|
|
155
|
+
' <link rel="icon" type="image/svg+xml" href="/favicon.svg" />\n' +
|
|
156
|
+
' <link rel="manifest" href="/manifest.webmanifest" />\n' +
|
|
157
|
+
` <title>${path.basename(name)}</title>\n` +
|
|
158
|
+
' </head>\n <body>\n <div id="root"></div>\n </body>\n</html>\n',
|
|
159
|
+
'client/public/favicon.svg':
|
|
160
|
+
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">\n' +
|
|
161
|
+
' <defs>\n' +
|
|
162
|
+
' <linearGradient id="g" x1="0" y1="0" x2="1" y2="1">\n' +
|
|
163
|
+
' <stop offset="0" stop-color="#2563FF" />\n' +
|
|
164
|
+
' <stop offset="0.5" stop-color="#7C3AED" />\n' +
|
|
165
|
+
' <stop offset="1" stop-color="#22E3AB" />\n' +
|
|
166
|
+
' </linearGradient>\n' +
|
|
167
|
+
' </defs>\n' +
|
|
168
|
+
' <rect width="32" height="32" rx="7" fill="#080D11" />\n' +
|
|
169
|
+
' <path d="M9 10h14v3.2h-5.4V24h-3.2V13.2H9z" fill="url(#g)" />\n' +
|
|
170
|
+
'</svg>\n',
|
|
171
|
+
'client/public/robots.txt': 'User-agent: *\nAllow: /\n',
|
|
172
|
+
'client/public/manifest.webmanifest':
|
|
173
|
+
JSON.stringify(
|
|
174
|
+
{
|
|
175
|
+
name: path.basename(name),
|
|
176
|
+
short_name: path.basename(name),
|
|
177
|
+
start_url: '/',
|
|
178
|
+
display: 'standalone',
|
|
179
|
+
background_color: '#080D11',
|
|
180
|
+
theme_color: '#080D11',
|
|
181
|
+
icons: [{ src: '/favicon.svg', type: 'image/svg+xml', sizes: 'any' }],
|
|
182
|
+
},
|
|
183
|
+
null,
|
|
184
|
+
4,
|
|
185
|
+
) + '\n',
|
|
186
|
+
'client/public/images/.gitkeep': '# Place images and other static assets here; served at /images/*.\n',
|
|
187
|
+
'client/toil.tsx':
|
|
188
|
+
"import { routes, layout, notFound } from 'toiljs/routes';\n\n" +
|
|
189
|
+
styleImportLines(features).join('\n') +
|
|
190
|
+
'\n\n' +
|
|
191
|
+
'Toil.mount(routes, layout, notFound);\n',
|
|
192
|
+
[`client/${styleEntry(features.preprocessor)}`]: DEFAULT_STYLE_CONTENT,
|
|
193
|
+
'client/components/.gitkeep': '# Place shared React components here.\n',
|
|
97
194
|
'toil-env.d.ts': TOIL_ENV_DTS,
|
|
195
|
+
'toilconfig.json':
|
|
196
|
+
JSON.stringify(
|
|
197
|
+
{
|
|
198
|
+
entries: ['server/main.ts'],
|
|
199
|
+
targets: {
|
|
200
|
+
release: {
|
|
201
|
+
outFile: 'build/server/release.wasm',
|
|
202
|
+
textFile: 'build/server/release.wat',
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
options: {
|
|
206
|
+
sourceMap: false,
|
|
207
|
+
optimizeLevel: 3,
|
|
208
|
+
shrinkLevel: 1,
|
|
209
|
+
converge: true,
|
|
210
|
+
noAssert: false,
|
|
211
|
+
enable: [
|
|
212
|
+
'sign-extension',
|
|
213
|
+
'mutable-globals',
|
|
214
|
+
'nontrapping-f2i',
|
|
215
|
+
'bulk-memory',
|
|
216
|
+
'simd',
|
|
217
|
+
'reference-types',
|
|
218
|
+
'multi-value',
|
|
219
|
+
],
|
|
220
|
+
runtime: 'stub',
|
|
221
|
+
memoryBase: 0,
|
|
222
|
+
initialMemory: 1,
|
|
223
|
+
debug: false,
|
|
224
|
+
trapMode: 'allow',
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
null,
|
|
228
|
+
4,
|
|
229
|
+
) + '\n',
|
|
230
|
+
'server/tsconfig.json':
|
|
231
|
+
JSON.stringify(
|
|
232
|
+
{
|
|
233
|
+
extends: 'toilscript/std/assembly.json',
|
|
234
|
+
include: ['./**/*.ts'],
|
|
235
|
+
},
|
|
236
|
+
null,
|
|
237
|
+
4,
|
|
238
|
+
) + '\n',
|
|
239
|
+
'server/index.ts': 'export function add(a: i32, b: i32): i32 {\n return a + b;\n}\n',
|
|
240
|
+
'server/main.ts':
|
|
241
|
+
"import { add } from './index';\n\n" +
|
|
242
|
+
'@main\nfunction run(): i32 {\n return add(40, 2);\n}\n',
|
|
98
243
|
'README.md': ['# ' + path.basename(name), '', 'A [toiljs](https://toil.org) app.', '', '## Develop', '', ' npm install', ' npm run dev', '', '## Build', '', ' npm run build', ''].join('\n'),
|
|
99
244
|
'client/layout.tsx': `import { type ReactNode } from 'react';
|
|
100
245
|
|
|
101
|
-
import { Link } from 'toiljs/client';
|
|
102
|
-
|
|
103
|
-
const styles = \`
|
|
104
|
-
:root { color-scheme: dark; }
|
|
105
|
-
body { margin: 0; background: #080D11; color: #F5F6FA; font-family: system-ui, -apple-system, sans-serif; line-height: 1.6; }
|
|
106
|
-
a { color: #2563FF; text-decoration: none; }
|
|
107
|
-
a:hover { color: #22E3AB; }
|
|
108
|
-
code { background: #11161f; color: #22E3AB; padding: 0.1rem 0.4rem; border-radius: 4px; font-size: 0.9em; }
|
|
109
|
-
h1 { background: linear-gradient(90deg, #2563FF, #7C3AED, #22E3AB); -webkit-background-clip: text; background-clip: text; color: transparent; }
|
|
110
|
-
\`;
|
|
111
|
-
|
|
112
246
|
export default function Layout({ children }: { children?: ReactNode }) {
|
|
113
247
|
return (
|
|
114
248
|
<div style={{ maxWidth: 680, margin: '0 auto', padding: '3rem 1.5rem' }}>
|
|
115
|
-
<style>{styles}</style>
|
|
116
249
|
<header
|
|
117
250
|
style={{
|
|
118
251
|
display: 'flex',
|
|
@@ -124,7 +257,7 @@ export default function Layout({ children }: { children?: ReactNode }) {
|
|
|
124
257
|
}}>
|
|
125
258
|
<strong style={{ color: '#2563FF', fontSize: '1.1rem' }}>${path.basename(name)}</strong>
|
|
126
259
|
<nav style={{ display: 'flex', gap: '1rem' }}>
|
|
127
|
-
<Link href="/">home</Link>${template === 'app' ? '\n <Link href="/about">about</Link>' : ''}
|
|
260
|
+
<Toil.Link href="/">home</Toil.Link>${template === 'app' ? '\n <Toil.Link href="/about">about</Toil.Link>' : ''}
|
|
128
261
|
</nav>
|
|
129
262
|
</header>
|
|
130
263
|
{children}
|
|
@@ -133,31 +266,39 @@ export default function Layout({ children }: { children?: ReactNode }) {
|
|
|
133
266
|
}
|
|
134
267
|
`,
|
|
135
268
|
'client/routes/index.tsx':
|
|
136
|
-
"import { Link } from 'toiljs/client';\n\n" +
|
|
137
269
|
'export default function Home() {\n' +
|
|
138
270
|
' return (\n <main>\n' +
|
|
139
271
|
' <h1>Welcome to toiljs</h1>\n' +
|
|
140
272
|
' <p>File-based routing, bundled by Vite, zero config.</p>\n' +
|
|
141
273
|
(template === 'app'
|
|
142
|
-
? ' <p>\n <Link href="/about">About</Link> · <Link href="/blog/42">Blog post 42</Link>\n </p>\n'
|
|
274
|
+
? ' <p>\n <Toil.Link href="/about">About</Toil.Link> · <Toil.Link href="/blog/42">Blog post 42</Toil.Link>\n </p>\n'
|
|
143
275
|
: '') +
|
|
144
276
|
' </main>\n );\n}\n',
|
|
145
277
|
};
|
|
146
278
|
|
|
147
279
|
if (template === 'app') {
|
|
148
280
|
files['client/routes/about.tsx'] =
|
|
149
|
-
"import { Link } from 'toiljs/client';\n\n" +
|
|
150
281
|
'export default function About() {\n' +
|
|
151
282
|
' return (\n <main>\n <h1>About</h1>\n' +
|
|
152
283
|
' <p>\n This page is served by <code>client/routes/about.tsx</code>.\n </p>\n' +
|
|
153
|
-
' <Link href="/">Back home</Link>\n </main>\n );\n}\n';
|
|
284
|
+
' <Toil.Link href="/">Back home</Toil.Link>\n </main>\n );\n}\n';
|
|
154
285
|
files['client/routes/blog/[id].tsx'] =
|
|
155
|
-
"import { Link, useParams } from 'toiljs/client';\n\n" +
|
|
156
286
|
'export default function BlogPost() {\n' +
|
|
157
|
-
' const { id } = useParams();\n' +
|
|
287
|
+
' const { id } = Toil.useParams();\n' +
|
|
158
288
|
' return (\n <main>\n <h1>Blog post {id}</h1>\n' +
|
|
159
289
|
' <p>\n Dynamic route from <code>client/routes/blog/[id].tsx</code>.\n </p>\n' +
|
|
160
|
-
' <Link href="/">Back home</Link>\n </main>\n );\n}\n';
|
|
290
|
+
' <Toil.Link href="/">Back home</Toil.Link>\n </main>\n );\n}\n';
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
if (features.tailwind) {
|
|
294
|
+
files[`client/${TAILWIND_ENTRY}`] = TAILWIND_CSS;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
// Selected AI-assistant pointer files at the root (committed). The real docs are always seeded
|
|
298
|
+
// under .toil/docs (gitignored; regenerated by dev/build) since the framework manages them.
|
|
299
|
+
Object.assign(files, aiHelperFiles(aiTools));
|
|
300
|
+
for (const [name, content] of Object.entries(TOIL_DOCS)) {
|
|
301
|
+
files[`.toil/docs/${name}`] = content;
|
|
161
302
|
}
|
|
162
303
|
|
|
163
304
|
return files;
|
|
@@ -171,27 +312,10 @@ async function writeFiles(dir: string, files: Record<string, string>): Promise<v
|
|
|
171
312
|
}
|
|
172
313
|
}
|
|
173
314
|
|
|
174
|
-
function run(cmd: string, args: string[], cwd: string): Promise<void> {
|
|
175
|
-
return new Promise((resolve, reject) => {
|
|
176
|
-
// On Windows `npm`/`pnpm`/`yarn` are `.cmd` shims that need a shell to launch. Passing an
|
|
177
|
-
// args array together with `shell: true` is deprecated (DEP0190), so pass the whole command
|
|
178
|
-
// as one string there (the args are fixed, not user input). POSIX runs it directly.
|
|
179
|
-
const onWindows = process.platform === 'win32';
|
|
180
|
-
const child = onWindows
|
|
181
|
-
? spawn([cmd, ...args].join(' '), { cwd, stdio: 'ignore', shell: true })
|
|
182
|
-
: spawn(cmd, args, { cwd, stdio: 'ignore' });
|
|
183
|
-
child.on('error', reject);
|
|
184
|
-
child.on('close', (code) =>
|
|
185
|
-
code === 0 ? resolve() : reject(new Error(`${cmd} exited with code ${String(code)}`)),
|
|
186
|
-
);
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
|
|
190
315
|
/** Runs the create flow (interactive unless `--yes`). */
|
|
191
316
|
export async function runCreate(opts: CreateOptions): Promise<void> {
|
|
192
317
|
intro(accent(' toiljs create '));
|
|
193
318
|
|
|
194
|
-
// 1. Project name
|
|
195
319
|
let name = opts.name;
|
|
196
320
|
if (!name) {
|
|
197
321
|
if (opts.yes) {
|
|
@@ -216,10 +340,13 @@ export async function runCreate(opts: CreateOptions): Promise<void> {
|
|
|
216
340
|
process.exit(1);
|
|
217
341
|
}
|
|
218
342
|
|
|
219
|
-
const targetDir =
|
|
343
|
+
const targetDir = resolveProjectDir(opts.cwd, name);
|
|
344
|
+
if (targetDir === null) {
|
|
345
|
+
cancel('Project name must stay inside the current directory (no "..", no absolute paths).');
|
|
346
|
+
process.exit(1);
|
|
347
|
+
}
|
|
220
348
|
const rel = path.relative(opts.cwd, targetDir) || '.';
|
|
221
349
|
|
|
222
|
-
// 2. Guard against clobbering a non-empty dir
|
|
223
350
|
if (!(await isEmptyDir(targetDir))) {
|
|
224
351
|
if (opts.yes) {
|
|
225
352
|
cancel(`Directory ${pc.cyan(rel)} is not empty.`);
|
|
@@ -236,7 +363,6 @@ export async function runCreate(opts: CreateOptions): Promise<void> {
|
|
|
236
363
|
}
|
|
237
364
|
}
|
|
238
365
|
|
|
239
|
-
// 3. Template
|
|
240
366
|
let template: Template = opts.template ?? 'app';
|
|
241
367
|
if (!opts.template && !opts.yes) {
|
|
242
368
|
const templateOptions: TemplateOption[] = [
|
|
@@ -248,10 +374,46 @@ export async function runCreate(opts: CreateOptions): Promise<void> {
|
|
|
248
374
|
template = choice === 'minimal' ? 'minimal' : 'app';
|
|
249
375
|
}
|
|
250
376
|
|
|
251
|
-
|
|
377
|
+
let preprocessor: Preprocessor = opts.preprocessor ?? 'css';
|
|
378
|
+
let tailwind = opts.tailwind ?? false;
|
|
379
|
+
if (!opts.yes) {
|
|
380
|
+
if (opts.preprocessor === undefined) {
|
|
381
|
+
const choice = await select<Preprocessor>({
|
|
382
|
+
message: 'Styling',
|
|
383
|
+
options: PREPROCESSORS.map((value) => ({ value, label: PREPROCESSOR_LABEL[value] })),
|
|
384
|
+
initialValue: 'css',
|
|
385
|
+
});
|
|
386
|
+
bail(choice);
|
|
387
|
+
preprocessor = choice;
|
|
388
|
+
}
|
|
389
|
+
if (opts.tailwind === undefined) {
|
|
390
|
+
const tw = await confirm({ message: 'Add Tailwind CSS?', initialValue: false });
|
|
391
|
+
bail(tw);
|
|
392
|
+
tailwind = tw;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
const features: StyleFeatures = { preprocessor, tailwind };
|
|
396
|
+
|
|
397
|
+
// AI assistant files: --ai = all, --no-ai = none, otherwise ask (default: all selected).
|
|
398
|
+
let aiTools: string[] = opts.ai === false ? [] : [...AI_HELPER_IDS];
|
|
399
|
+
if (opts.ai === undefined && !opts.yes) {
|
|
400
|
+
const picked = await multiselect<string>({
|
|
401
|
+
message: 'AI assistant files (read by Claude, Cursor, Codex, Copilot)',
|
|
402
|
+
options: AI_HELPERS.map((h) => ({ value: h.id, label: h.label })),
|
|
403
|
+
initialValues: [...AI_HELPER_IDS],
|
|
404
|
+
required: false,
|
|
405
|
+
});
|
|
406
|
+
bail(picked);
|
|
407
|
+
aiTools = picked;
|
|
408
|
+
}
|
|
409
|
+
|
|
252
410
|
let initGit = opts.git ?? false;
|
|
253
411
|
let install = opts.install ?? false;
|
|
254
412
|
const pm = opts.pm ?? 'npm';
|
|
413
|
+
if (!isPackageManager(pm)) {
|
|
414
|
+
cancel(`Unsupported package manager: ${pm} (use npm, pnpm, yarn, or bun).`);
|
|
415
|
+
process.exit(1);
|
|
416
|
+
}
|
|
255
417
|
if (!opts.yes) {
|
|
256
418
|
if (opts.git === undefined) {
|
|
257
419
|
const g = await confirm({ message: 'Initialize a git repository?', initialValue: true });
|
|
@@ -265,13 +427,11 @@ export async function runCreate(opts: CreateOptions): Promise<void> {
|
|
|
265
427
|
}
|
|
266
428
|
}
|
|
267
429
|
|
|
268
|
-
// 5. Scaffold
|
|
269
430
|
const s = spinner();
|
|
270
431
|
s.start('Scaffolding project');
|
|
271
|
-
await writeFiles(targetDir, scaffold(name, template));
|
|
432
|
+
await writeFiles(targetDir, scaffold(name, template, features, aiTools));
|
|
272
433
|
s.stop(`Scaffolded ${pc.cyan(rel)}`);
|
|
273
434
|
|
|
274
|
-
// 6. git init (best-effort)
|
|
275
435
|
if (initGit) {
|
|
276
436
|
const g = spinner();
|
|
277
437
|
g.start('Initializing git repository');
|
|
@@ -284,7 +444,6 @@ export async function runCreate(opts: CreateOptions): Promise<void> {
|
|
|
284
444
|
}
|
|
285
445
|
}
|
|
286
446
|
|
|
287
|
-
// 7. Install (best-effort)
|
|
288
447
|
if (install) {
|
|
289
448
|
const i = spinner();
|
|
290
449
|
i.start(`Installing dependencies with ${pm}`);
|
|
@@ -297,7 +456,6 @@ export async function runCreate(opts: CreateOptions): Promise<void> {
|
|
|
297
456
|
}
|
|
298
457
|
}
|
|
299
458
|
|
|
300
|
-
// 8. Next steps
|
|
301
459
|
const steps: string[] = [];
|
|
302
460
|
if (rel !== '.') steps.push(`cd ${rel}`);
|
|
303
461
|
if (!install) steps.push('npm install');
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure description of toiljs's optional client styling features — a CSS preprocessor and Tailwind —
|
|
3
|
+
* shared by `create` (scaffold) and `configure` (toggle on existing projects). Dependency-light
|
|
4
|
+
* (no node IO) so it can be unit-tested; the file writes and package-manager calls live in the
|
|
5
|
+
* commands. Preprocessor and Tailwind are independent: Tailwind lives in its own `.css` entry so
|
|
6
|
+
* it never passes through (and breaks on) a preprocessor's `@import` resolution.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/** Supported CSS preprocessor (`css` = none). */
|
|
10
|
+
export type Preprocessor = 'css' | 'sass' | 'less' | 'stylus';
|
|
11
|
+
|
|
12
|
+
/** The two independently-toggleable styling features of a project. */
|
|
13
|
+
export interface StyleFeatures {
|
|
14
|
+
readonly preprocessor: Preprocessor;
|
|
15
|
+
readonly tailwind: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const PREPROCESSORS: readonly Preprocessor[] = ['css', 'sass', 'less', 'stylus'];
|
|
19
|
+
|
|
20
|
+
/** Main stylesheet extension for each preprocessor. */
|
|
21
|
+
export const STYLE_EXT: Record<Preprocessor, string> = {
|
|
22
|
+
css: 'css',
|
|
23
|
+
sass: 'scss',
|
|
24
|
+
less: 'less',
|
|
25
|
+
stylus: 'styl',
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/** npm package that enables each preprocessor in Vite (plain CSS needs none). */
|
|
29
|
+
export const PREPROCESSOR_PKG: Record<Preprocessor, string | null> = {
|
|
30
|
+
css: null,
|
|
31
|
+
sass: 'sass',
|
|
32
|
+
less: 'less',
|
|
33
|
+
stylus: 'stylus',
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/** Tailwind v4 packages. The framework auto-wires the Vite plugin when `@tailwindcss/vite` resolves. */
|
|
37
|
+
export const TAILWIND_PKGS: readonly string[] = ['tailwindcss', '@tailwindcss/vite'];
|
|
38
|
+
|
|
39
|
+
/** Pinned versions for every package these features may install. */
|
|
40
|
+
export const PKG_VERSION: Record<string, string> = {
|
|
41
|
+
sass: '^1.83.0',
|
|
42
|
+
less: '^4.2.1',
|
|
43
|
+
stylus: '^0.64.0',
|
|
44
|
+
tailwindcss: '^4.0.0',
|
|
45
|
+
'@tailwindcss/vite': '^4.0.0',
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/** Dedicated Tailwind entry (kept `.css` so no preprocessor touches its `@import`). */
|
|
49
|
+
export const TAILWIND_ENTRY = 'styles/tailwind.css';
|
|
50
|
+
export const TAILWIND_CSS = `@import 'tailwindcss';\n`;
|
|
51
|
+
|
|
52
|
+
/** Path (relative to `client/`) of the main stylesheet for a preprocessor. */
|
|
53
|
+
export function styleEntry(p: Preprocessor): string {
|
|
54
|
+
return `styles/main.${STYLE_EXT[p]}`;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** The preprocessor whose main stylesheet uses `ext` (with or without a leading dot), or null. */
|
|
58
|
+
export function preprocessorForExt(ext: string): Preprocessor | null {
|
|
59
|
+
const e = ext.replace(/^\./, '');
|
|
60
|
+
if (e === 'sass') return 'sass';
|
|
61
|
+
return PREPROCESSORS.find((p) => STYLE_EXT[p] === e) ?? null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Packages required by a feature set (preprocessor package + Tailwind packages). */
|
|
65
|
+
export function requiredPackages(f: StyleFeatures): string[] {
|
|
66
|
+
const pkgs: string[] = [];
|
|
67
|
+
const pp = PREPROCESSOR_PKG[f.preprocessor];
|
|
68
|
+
if (pp) pkgs.push(pp);
|
|
69
|
+
if (f.tailwind) pkgs.push(...TAILWIND_PKGS);
|
|
70
|
+
return pkgs;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Managed packages to add and remove when moving from `from` to `to`. */
|
|
74
|
+
export function packageDiff(
|
|
75
|
+
from: StyleFeatures,
|
|
76
|
+
to: StyleFeatures,
|
|
77
|
+
): { add: string[]; remove: string[] } {
|
|
78
|
+
const want = new Set(requiredPackages(to));
|
|
79
|
+
const had = new Set(requiredPackages(from));
|
|
80
|
+
return {
|
|
81
|
+
add: [...want].filter((p) => !had.has(p)),
|
|
82
|
+
remove: [...had].filter((p) => !want.has(p)),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** The side-effect style imports for the app entry, Tailwind first so app CSS can override it. */
|
|
87
|
+
export function styleImportLines(f: StyleFeatures): string[] {
|
|
88
|
+
const lines: string[] = [];
|
|
89
|
+
if (f.tailwind) lines.push(`import './${TAILWIND_ENTRY}';`);
|
|
90
|
+
lines.push(`import './${styleEntry(f.preprocessor)}';`);
|
|
91
|
+
return lines;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Rewrites the `./styles/*` side-effect imports in an app entry (`client/toil.tsx`) to match
|
|
96
|
+
* `features`, preserving the rest of the file. Existing style imports are removed and the new
|
|
97
|
+
* block is placed after the `toiljs/routes` import (or the last import, or the top).
|
|
98
|
+
*/
|
|
99
|
+
export function setStyleImports(source: string, f: StyleFeatures): string {
|
|
100
|
+
const stripped = source.replace(/^[ \t]*import\s+['"]\.\/styles\/[^'"]+['"];?[ \t]*\r?\n/gm, '');
|
|
101
|
+
const block = styleImportLines(f).join('\n') + '\n';
|
|
102
|
+
|
|
103
|
+
const lines = stripped.split('\n');
|
|
104
|
+
const routesIdx = lines.findIndex((l) => /from\s+['"]toiljs\/routes['"]/.test(l));
|
|
105
|
+
let insertAt: number;
|
|
106
|
+
if (routesIdx !== -1) {
|
|
107
|
+
insertAt = routesIdx + 1;
|
|
108
|
+
} else {
|
|
109
|
+
const lastImport = lines.reduce((acc, l, i) => (/^\s*import\s/.test(l) ? i : acc), -1);
|
|
110
|
+
insertAt = lastImport + 1;
|
|
111
|
+
}
|
|
112
|
+
const head = lines.slice(0, insertAt).join('\n');
|
|
113
|
+
const tail = lines.slice(insertAt).join('\n');
|
|
114
|
+
return `${head}\n\n${block}\n${tail}`.replace(/\n{3,}/g, '\n\n');
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/** Detects the active preprocessor from a project's combined dependency map. */
|
|
118
|
+
export function detectPreprocessor(deps: Record<string, string>): Preprocessor {
|
|
119
|
+
if ('sass' in deps) return 'sass';
|
|
120
|
+
if ('less' in deps) return 'less';
|
|
121
|
+
if ('stylus' in deps) return 'stylus';
|
|
122
|
+
return 'css';
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** Whether Tailwind is installed in a project's combined dependency map. */
|
|
126
|
+
export function detectTailwind(deps: Record<string, string>): boolean {
|
|
127
|
+
return '@tailwindcss/vite' in deps || 'tailwindcss' in deps;
|
|
128
|
+
}
|