toiljs 0.0.3 → 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 +169 -56
- 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.d.ts +1 -0
- package/build/compiler/generate.js +139 -21
- package/build/compiler/index.d.ts +5 -2
- package/build/compiler/index.js +5 -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 +228 -67
- 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 +180 -33
- package/src/compiler/index.ts +7 -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,17 +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 {
|
|
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';
|
|
11
22
|
import pc from 'picocolors';
|
|
12
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';
|
|
13
36
|
import { accent, dim, version } from './ui.js';
|
|
37
|
+
import { isPackageManager, isValidName, resolveProjectDir } from './validate.js';
|
|
14
38
|
|
|
15
39
|
export type Template = 'app' | 'minimal';
|
|
16
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
|
+
|
|
17
61
|
/** A selectable template in the `create` wizard. */
|
|
18
62
|
interface TemplateOption {
|
|
19
63
|
readonly value: Template;
|
|
@@ -24,6 +68,10 @@ interface TemplateOption {
|
|
|
24
68
|
export interface CreateOptions {
|
|
25
69
|
readonly name?: string;
|
|
26
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;
|
|
27
75
|
readonly install?: boolean;
|
|
28
76
|
readonly git?: boolean;
|
|
29
77
|
readonly pm?: string;
|
|
@@ -39,77 +87,165 @@ function bail<T>(value: T | symbol): asserts value is T {
|
|
|
39
87
|
}
|
|
40
88
|
}
|
|
41
89
|
|
|
42
|
-
function isValidName(name: string): true | string {
|
|
43
|
-
if (!name.trim()) return 'Please enter a project name.';
|
|
44
|
-
if (!/^[a-z0-9._@/-]+$/i.test(name)) return 'Use letters, numbers, dashes, dots or slashes.';
|
|
45
|
-
return true;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
90
|
async function isEmptyDir(dir: string): Promise<boolean> {
|
|
49
91
|
try {
|
|
50
92
|
const entries = await fs.readdir(dir);
|
|
51
93
|
return entries.length === 0;
|
|
52
94
|
} catch {
|
|
53
|
-
return true;
|
|
95
|
+
return true;
|
|
54
96
|
}
|
|
55
97
|
}
|
|
56
98
|
|
|
57
99
|
/** Builds the full file map (relative path → contents) for a scaffolded project. */
|
|
58
|
-
function scaffold(
|
|
100
|
+
function scaffold(
|
|
101
|
+
name: string,
|
|
102
|
+
template: Template,
|
|
103
|
+
features: StyleFeatures,
|
|
104
|
+
aiTools: readonly string[],
|
|
105
|
+
): Record<string, string> {
|
|
59
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
|
+
}
|
|
60
118
|
const pkg = {
|
|
61
119
|
name: path.basename(name),
|
|
62
120
|
private: true,
|
|
63
121
|
type: 'module',
|
|
64
122
|
scripts: {
|
|
65
123
|
dev: 'toiljs dev',
|
|
66
|
-
build: 'toiljs build',
|
|
124
|
+
build: 'toiljs build && toilscript --target release',
|
|
125
|
+
'build:client': 'toiljs build',
|
|
126
|
+
'build:server': 'toilscript --target release',
|
|
67
127
|
lint: 'eslint client',
|
|
68
128
|
typecheck: 'tsc --noEmit',
|
|
69
|
-
format: 'prettier --write "client/**/*.{ts,tsx}"',
|
|
129
|
+
format: 'prettier --write "client/**/*.{ts,tsx,css,scss,less}" "client/public/**/*.html"',
|
|
70
130
|
},
|
|
71
131
|
dependencies: {
|
|
72
132
|
toiljs: `^${toilVersion}`,
|
|
73
133
|
react: '^19.2.6',
|
|
74
134
|
'react-dom': '^19.2.6',
|
|
75
135
|
},
|
|
76
|
-
devDependencies
|
|
77
|
-
'@types/react': '^19.2.15',
|
|
78
|
-
'@types/react-dom': '^19.2.3',
|
|
79
|
-
eslint: '^10.2.0',
|
|
80
|
-
prettier: '^3.8.1',
|
|
81
|
-
typescript: '^6.0.3',
|
|
82
|
-
},
|
|
136
|
+
devDependencies,
|
|
83
137
|
};
|
|
84
138
|
|
|
85
139
|
const files: Record<string, string> = {
|
|
86
140
|
'package.json': JSON.stringify(pkg, null, 4) + '\n',
|
|
87
141
|
'toil.config.ts':
|
|
88
142
|
"import { defineConfig } from 'toiljs/compiler';\n\n" +
|
|
89
|
-
'export default defineConfig({
|
|
143
|
+
'export default defineConfig({});\n',
|
|
90
144
|
'tsconfig.json':
|
|
91
145
|
'{\n "extends": "toiljs/tsconfig",\n "include": ["client", "toil-env.d.ts"]\n}\n',
|
|
92
146
|
'eslint.config.js': "import toiljs from 'toiljs/eslint';\n\nexport default toiljs;\n",
|
|
93
147
|
'.prettierrc': '"toiljs/prettier"\n',
|
|
94
|
-
'.gitignore': 'node_modules\
|
|
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',
|
|
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',
|
|
95
243
|
'README.md': ['# ' + path.basename(name), '', 'A [toiljs](https://toil.org) app.', '', '## Develop', '', ' npm install', ' npm run dev', '', '## Build', '', ' npm run build', ''].join('\n'),
|
|
96
244
|
'client/layout.tsx': `import { type ReactNode } from 'react';
|
|
97
245
|
|
|
98
|
-
import { Link } from 'toiljs/client';
|
|
99
|
-
|
|
100
|
-
const styles = \`
|
|
101
|
-
:root { color-scheme: dark; }
|
|
102
|
-
body { margin: 0; background: #080D11; color: #F5F6FA; font-family: system-ui, -apple-system, sans-serif; line-height: 1.6; }
|
|
103
|
-
a { color: #2563FF; text-decoration: none; }
|
|
104
|
-
a:hover { color: #22E3AB; }
|
|
105
|
-
code { background: #11161f; color: #22E3AB; padding: 0.1rem 0.4rem; border-radius: 4px; font-size: 0.9em; }
|
|
106
|
-
h1 { background: linear-gradient(90deg, #2563FF, #7C3AED, #22E3AB); -webkit-background-clip: text; background-clip: text; color: transparent; }
|
|
107
|
-
\`;
|
|
108
|
-
|
|
109
246
|
export default function Layout({ children }: { children?: ReactNode }) {
|
|
110
247
|
return (
|
|
111
248
|
<div style={{ maxWidth: 680, margin: '0 auto', padding: '3rem 1.5rem' }}>
|
|
112
|
-
<style>{styles}</style>
|
|
113
249
|
<header
|
|
114
250
|
style={{
|
|
115
251
|
display: 'flex',
|
|
@@ -121,7 +257,7 @@ export default function Layout({ children }: { children?: ReactNode }) {
|
|
|
121
257
|
}}>
|
|
122
258
|
<strong style={{ color: '#2563FF', fontSize: '1.1rem' }}>${path.basename(name)}</strong>
|
|
123
259
|
<nav style={{ display: 'flex', gap: '1rem' }}>
|
|
124
|
-
<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>' : ''}
|
|
125
261
|
</nav>
|
|
126
262
|
</header>
|
|
127
263
|
{children}
|
|
@@ -130,31 +266,39 @@ export default function Layout({ children }: { children?: ReactNode }) {
|
|
|
130
266
|
}
|
|
131
267
|
`,
|
|
132
268
|
'client/routes/index.tsx':
|
|
133
|
-
"import { Link } from 'toiljs/client';\n\n" +
|
|
134
269
|
'export default function Home() {\n' +
|
|
135
270
|
' return (\n <main>\n' +
|
|
136
271
|
' <h1>Welcome to toiljs</h1>\n' +
|
|
137
272
|
' <p>File-based routing, bundled by Vite, zero config.</p>\n' +
|
|
138
273
|
(template === 'app'
|
|
139
|
-
? ' <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'
|
|
140
275
|
: '') +
|
|
141
276
|
' </main>\n );\n}\n',
|
|
142
277
|
};
|
|
143
278
|
|
|
144
279
|
if (template === 'app') {
|
|
145
280
|
files['client/routes/about.tsx'] =
|
|
146
|
-
"import { Link } from 'toiljs/client';\n\n" +
|
|
147
281
|
'export default function About() {\n' +
|
|
148
282
|
' return (\n <main>\n <h1>About</h1>\n' +
|
|
149
283
|
' <p>\n This page is served by <code>client/routes/about.tsx</code>.\n </p>\n' +
|
|
150
|
-
' <Link href="/">Back home</Link>\n </main>\n );\n}\n';
|
|
284
|
+
' <Toil.Link href="/">Back home</Toil.Link>\n </main>\n );\n}\n';
|
|
151
285
|
files['client/routes/blog/[id].tsx'] =
|
|
152
|
-
"import { Link, useParams } from 'toiljs/client';\n\n" +
|
|
153
286
|
'export default function BlogPost() {\n' +
|
|
154
|
-
' const { id } = useParams();\n' +
|
|
287
|
+
' const { id } = Toil.useParams();\n' +
|
|
155
288
|
' return (\n <main>\n <h1>Blog post {id}</h1>\n' +
|
|
156
289
|
' <p>\n Dynamic route from <code>client/routes/blog/[id].tsx</code>.\n </p>\n' +
|
|
157
|
-
' <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;
|
|
158
302
|
}
|
|
159
303
|
|
|
160
304
|
return files;
|
|
@@ -168,27 +312,10 @@ async function writeFiles(dir: string, files: Record<string, string>): Promise<v
|
|
|
168
312
|
}
|
|
169
313
|
}
|
|
170
314
|
|
|
171
|
-
function run(cmd: string, args: string[], cwd: string): Promise<void> {
|
|
172
|
-
return new Promise((resolve, reject) => {
|
|
173
|
-
// On Windows `npm`/`pnpm`/`yarn` are `.cmd` shims that need a shell to launch. Passing an
|
|
174
|
-
// args array together with `shell: true` is deprecated (DEP0190), so pass the whole command
|
|
175
|
-
// as one string there (the args are fixed, not user input). POSIX runs it directly.
|
|
176
|
-
const onWindows = process.platform === 'win32';
|
|
177
|
-
const child = onWindows
|
|
178
|
-
? spawn([cmd, ...args].join(' '), { cwd, stdio: 'ignore', shell: true })
|
|
179
|
-
: spawn(cmd, args, { cwd, stdio: 'ignore' });
|
|
180
|
-
child.on('error', reject);
|
|
181
|
-
child.on('close', (code) =>
|
|
182
|
-
code === 0 ? resolve() : reject(new Error(`${cmd} exited with code ${String(code)}`)),
|
|
183
|
-
);
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
|
-
|
|
187
315
|
/** Runs the create flow (interactive unless `--yes`). */
|
|
188
316
|
export async function runCreate(opts: CreateOptions): Promise<void> {
|
|
189
317
|
intro(accent(' toiljs create '));
|
|
190
318
|
|
|
191
|
-
// 1. Project name
|
|
192
319
|
let name = opts.name;
|
|
193
320
|
if (!name) {
|
|
194
321
|
if (opts.yes) {
|
|
@@ -213,10 +340,13 @@ export async function runCreate(opts: CreateOptions): Promise<void> {
|
|
|
213
340
|
process.exit(1);
|
|
214
341
|
}
|
|
215
342
|
|
|
216
|
-
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
|
+
}
|
|
217
348
|
const rel = path.relative(opts.cwd, targetDir) || '.';
|
|
218
349
|
|
|
219
|
-
// 2. Guard against clobbering a non-empty dir
|
|
220
350
|
if (!(await isEmptyDir(targetDir))) {
|
|
221
351
|
if (opts.yes) {
|
|
222
352
|
cancel(`Directory ${pc.cyan(rel)} is not empty.`);
|
|
@@ -233,7 +363,6 @@ export async function runCreate(opts: CreateOptions): Promise<void> {
|
|
|
233
363
|
}
|
|
234
364
|
}
|
|
235
365
|
|
|
236
|
-
// 3. Template
|
|
237
366
|
let template: Template = opts.template ?? 'app';
|
|
238
367
|
if (!opts.template && !opts.yes) {
|
|
239
368
|
const templateOptions: TemplateOption[] = [
|
|
@@ -245,10 +374,46 @@ export async function runCreate(opts: CreateOptions): Promise<void> {
|
|
|
245
374
|
template = choice === 'minimal' ? 'minimal' : 'app';
|
|
246
375
|
}
|
|
247
376
|
|
|
248
|
-
|
|
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
|
+
|
|
249
410
|
let initGit = opts.git ?? false;
|
|
250
411
|
let install = opts.install ?? false;
|
|
251
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
|
+
}
|
|
252
417
|
if (!opts.yes) {
|
|
253
418
|
if (opts.git === undefined) {
|
|
254
419
|
const g = await confirm({ message: 'Initialize a git repository?', initialValue: true });
|
|
@@ -262,13 +427,11 @@ export async function runCreate(opts: CreateOptions): Promise<void> {
|
|
|
262
427
|
}
|
|
263
428
|
}
|
|
264
429
|
|
|
265
|
-
// 5. Scaffold
|
|
266
430
|
const s = spinner();
|
|
267
431
|
s.start('Scaffolding project');
|
|
268
|
-
await writeFiles(targetDir, scaffold(name, template));
|
|
432
|
+
await writeFiles(targetDir, scaffold(name, template, features, aiTools));
|
|
269
433
|
s.stop(`Scaffolded ${pc.cyan(rel)}`);
|
|
270
434
|
|
|
271
|
-
// 6. git init (best-effort)
|
|
272
435
|
if (initGit) {
|
|
273
436
|
const g = spinner();
|
|
274
437
|
g.start('Initializing git repository');
|
|
@@ -281,7 +444,6 @@ export async function runCreate(opts: CreateOptions): Promise<void> {
|
|
|
281
444
|
}
|
|
282
445
|
}
|
|
283
446
|
|
|
284
|
-
// 7. Install (best-effort)
|
|
285
447
|
if (install) {
|
|
286
448
|
const i = spinner();
|
|
287
449
|
i.start(`Installing dependencies with ${pm}`);
|
|
@@ -294,7 +456,6 @@ export async function runCreate(opts: CreateOptions): Promise<void> {
|
|
|
294
456
|
}
|
|
295
457
|
}
|
|
296
458
|
|
|
297
|
-
// 8. Next steps
|
|
298
459
|
const steps: string[] = [];
|
|
299
460
|
if (rel !== '.') steps.push(`cd ${rel}`);
|
|
300
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
|
+
}
|