diff --git a/Readme.md b/Readme.md index 1be49d3..d71f1d2 100644 --- a/Readme.md +++ b/Readme.md @@ -31,7 +31,7 @@ tsdev create {name} ``` -➜ tsdev --help +tsdev --help NAME: tsdev - Zero config modern typescript tooling @@ -39,15 +39,19 @@ USAGE: tsdev [global options] command [command options] Run a .ts file with zero config directly COMMANDS: - create Create a new application - dev This run the app in dev mode with file watching - build This builds the app for production. - prettier Will run pretty-quick - lint Will lint the application - help, h Shows a list of commands or help for one command + create Create a new application + dev This run the app in dev mode with file watching + build This builds the app for production. + dts Emit .d.ts files and bundle them + prettier Will run pretty-quick, prettify all staged files + lint Will lint the application + version, v Version of cli + help, h Shows a list of commands or help for one command GLOBAL OPTIONS: - --watch Run in watch mode (default: false) + --watch Run in watch mode (default: false) + --version, -v (default: false) + --help, -h show help (default: false) ``` ## Templates @@ -56,19 +60,4 @@ Templates are not stored here, this just allows us to keep this repo clean, all ## TODOs -Some of these might happen sooner than others. If you want something to be prioritized make an issue - -- [] Monorepo support, automatically bootstrap monorepos -- [] Support for `publishConfig` beyond just `pnpm`. This is super useful for typescript packages in monorepos -- [] Add basic CI setup for github actions (with all three package managers) -- [] Add defaults for publishing normal non-react packages -- [] Allow overwriting or extending eslint configs -- [] Add `graphql` template using [tsgql](https://github.com/modfy/tsgql). This will be `graphql` without having to write any `graphql` code at all, just typescript. -- [] Add `prisma` batteries -- [] Add support for all nextjs examples from https://github.com/vercel/next.js/tree/canary/examples -- [x] `tsdev filename` Automatically run any `.ts` or `.tsx` file with zero config - - [x] The `.ts` part of this is easy, it is basically what `tsdev dev filename` is - - The `.tsx` part is a bit more complicated, and will require making a custom version of `vite` that just runs file without a config file or a `.html` file or having to use `react-dom` yourself -- [] Make `vite` default template use filesystem routing -- [] Clone [`bun run` feature](https://twitter.com/jarredsumner/status/1454218996983623685?s=20) to allow really fast `npm run commands` -- [] Add support for [bun](https://bun.sh) once it becomes more stable \ No newline at end of file +Can find all TODOs on https://github.com/CryogenicPlanet/tsdev/issues/5 \ No newline at end of file diff --git a/cli.go b/cli.go index 2c79d0e..9837c2e 100644 --- a/cli.go +++ b/cli.go @@ -1,11 +1,19 @@ package main import ( + "fmt" "internal/commands" "github.com/urfave/cli/v2" ) +var ( + version = "dev" + commit = "none" + date = "unknown" + builtBy = "unknown" +) + func SetupCliApp() (cli.App, error) { cliCommands := []*cli.Command{ @@ -31,26 +39,30 @@ func SetupCliApp() (cli.App, error) { Name: "dts", Usage: "Will emit .d.ts files and bundle them", }, - // &cli.BoolFlag{ - // Name: "sourcemap", - // Usage: "Will emit source maps", - // }, - // &cli.StringFlag{ - // Name: "dist", - // Usage: "Set output directory", - // Value: "dist", - // }, }, Action: func(c *cli.Context) error { return commands.HandleBuildCommand(c.Args().First(), c.Bool("dts")) }, }, + { + Name: "dts", + Usage: "Emit .d.ts files and bundle them", + Action: func(c *cli.Context) error { + return commands.RunDts() + }, + }, { Name: "prettier", - Usage: "Will run pretty-quick", + Usage: "Will run pretty-quick, prettify all staged files", + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: "all", + Usage: "Will prettify all files instead of staged files", + }, + }, Action: func(c *cli.Context) error { - return commands.HandlePrettierCommand() + return commands.HandlePrettierCommand(c.Bool("all")) }, }, { @@ -66,6 +78,15 @@ func SetupCliApp() (cli.App, error) { return commands.HandleLintCommand(c.Bool("fix")) }, }, + { + Name: "version", + Usage: "Version of cli", + Aliases: []string{"v"}, + Action: func(c *cli.Context) error { + fmt.Printf("tsdev %s, commit %s, built at %s by %s", version, commit, date, builtBy) + return nil + }, + }, } app := &cli.App{ @@ -76,13 +97,22 @@ func SetupCliApp() (cli.App, error) { ArgsUsage: "Run a .ts file with zero config directly", Action: func(c *cli.Context) error { - return commands.HandleDefault(c.Bool("watch"), c.Args().Slice()) + if c.Bool("version") { + fmt.Printf("tsdev %s, commit %s, built at %s by %s", version, commit, date, builtBy) + return nil + } else { + return commands.HandleDefault(c.Bool("watch"), c.Args().Slice()) + } }, Flags: []cli.Flag{ &cli.BoolFlag{ Name: "watch", Usage: "Run in watch mode", }, + &cli.BoolFlag{ + Name: "version", + Aliases: []string{"v"}, + }, }, } diff --git a/installer/package.json b/installer/package.json index a8d2a1a..82293cb 100644 --- a/installer/package.json +++ b/installer/package.json @@ -1,6 +1,6 @@ { "name": "tsdev-installer", - "version": "0.0.11", + "version": "0.0.19", "description": "The installer for tsdev, a better tsdx", "scripts": { "postinstall": "node dist/postinstall.js install", diff --git a/internal/commands/build.go b/internal/commands/build.go index 1faa2b1..b777c1b 100644 --- a/internal/commands/build.go +++ b/internal/commands/build.go @@ -1,9 +1,7 @@ package commands import ( - "errors" "fmt" - "internal/types" "internal/utils" "os" "sync" @@ -13,35 +11,6 @@ import ( var buildWg sync.WaitGroup -func emitDts(cwd string, name string) error { - if _, err := os.Stat(types.BUNDLE_DTS_PATH); errors.Is(err, os.ErrNotExist) { - - fmt.Println("[WARN] You can only use --dts flag if you have installed tsdev as a dependency") - buildWg.Done() - return nil - } - utils.ExecWithOutput(cwd, "tsc", "--outDir", "dist/src/") - return bundleDts(cwd, name) -} - -func bundleDts(cwd string, name string) error { - - if _, err := os.Stat(types.BUNDLE_DTS_PATH); errors.Is(err, os.ErrNotExist) { - - if _, err := os.Stat(types.BUNDLE_BACKUP_DTS_PATH); errors.Is(err, os.ErrNotExist) { - fmt.Println("[WARN] You can only use --dts flag if you have installed tsdev as a dependency") - return errors.New("cannot find bundle-dts path") - } - utils.ExecWithOutput(cwd, "node", types.BUNDLE_BACKUP_DTS_PATH, "--name", name, "--main", "dist/src/index.d.ts", "--out", "../index.d.ts") - buildWg.Done() - return nil - } - - utils.ExecWithOutput(cwd, "node", types.BUNDLE_DTS_PATH, "--name", name, "--main", "dist/src/index.d.ts", "--out", "../index.d.ts") - buildWg.Done() - return nil -} - func buildCJS(entryPoint string, cwd string) { result := api.Build(api.BuildOptions{ EntryPoints: []string{entryPoint}, @@ -117,7 +86,7 @@ func HandleBuildCommand(entryPoint string, dts bool) error { buildWg.Add(1) name, err := utils.GetName() utils.CheckErr(err) - go emitDts(cwd, name) + go EmitDts(cwd, name) } buildWg.Wait() diff --git a/internal/commands/create.go b/internal/commands/create.go index 652099f..1178f0b 100644 --- a/internal/commands/create.go +++ b/internal/commands/create.go @@ -116,17 +116,30 @@ func createDir(name string) error { return nil } -// Will clone skeleton template -func cloneTemplate(name string) error { - - // Download templates from releases and unzip them - - return nil -} - // Will generate package json func generatePackageJson(name string) { + var prepareScript string + + switch projectConfig.PackageManager { + case types.Pnpm: + { + prepareScript = "pnpm build && pnpm dts" + } + case types.Yarn: + { + prepareScript = "yarn build && yarn dts" + } + case types.Npm: + { + prepareScript = "npm run build && npm run dts" + } + default: + { + prepareScript = "npm run build && npm run dts" + } + } + // Default package json packageJson := types.PackageJSON{ Name: name, @@ -135,8 +148,8 @@ func generatePackageJson(name string) { Main: "dist/index.js", Typings: "dist/index.d.ts", Module: "dist/index.es.js", - Files: []string{"dist"}, - Scripts: map[string]string{"start": "tsdev start", "build": "tsdev build", "dev": "tsdev dev", "lint": "tsdev lint"}, + Files: []string{"dist", "!dist/src"}, + Scripts: map[string]string{"start": "tsdev start", "build": "tsdev build", "dev": "tsdev dev", "lint": "tsdev lint", "dts": "tsdev dts", "prepare": prepareScript}, DevDependencies: map[string]string{"typescript": "latest", "husky": "latest", "prettier": "latest", "prettier-config-standard": "latest", "@cryogenicplanet/tsdev": "latest"}, Husky: map[string]map[string]string{"hooks": {"pre-commit": "tsdev prettier", "pre-push": "tsdev lint"}}, Engines: map[string]string{"node": ">12"}, @@ -160,7 +173,7 @@ func generatePackageJson(name string) { if projectConfig.Template == types.ViteLibraryModeTemplate { // Vite library mode exports https://vitejs.dev/guide/build.html#library-mode - packageJson.Exports = map[string]map[string]string{".": {"imports": "./dist/index.es.js", "exports": "./dist/index.umd.js"}} + packageJson.Exports = map[string]map[string]string{".": {"imports": "./dist/index.es.js", "require": "./dist/index.umd.js"}} } case types.NextTemplate: @@ -211,6 +224,8 @@ func downloadTemplate(dirName string) { switch projectConfig.Template { case types.BasicTemplate: utils.DownloadArchive("https://tsdev.vercel.app/templates/basic.zip", dirName) + case types.ExpressTemplate: + utils.DownloadArchive("https://tsdev.vercel.app/templates/express.zip", dirName) case types.ReactTemplate: utils.DownloadArchive("https://tsdev.vercel.app/templates/vite.zip", dirName) case types.NextTemplate: diff --git a/internal/commands/dts.go b/internal/commands/dts.go new file mode 100644 index 0000000..360cd24 --- /dev/null +++ b/internal/commands/dts.go @@ -0,0 +1,69 @@ +package commands + +import ( + "errors" + "fmt" + "internal/types" + "internal/utils" + "os" +) + +func EmitDts(cwd string, name string) error { + + packageJson, err := utils.ReadPackageJson(cwd + "/package.json") + + if err != nil { + fmt.Println("Could not read package.json", cwd+"./package.json") + buildWg.Done() + return err + } + + if _, err := os.Stat(types.BUNDLE_DTS_PATH); errors.Is(err, os.ErrNotExist) { + + if _, err := os.Stat(types.BUNDLE_BACKUP_DTS_PATH); errors.Is(err, os.ErrNotExist) { + fmt.Println("[WARN] You can only use --dts flag if you have installed tsdev as a dependency. Error:", err) + buildWg.Done() + return errors.New("cannot find bundle-dts path") + } + } + fmt.Println("Package manager is ", packageJson.TSDEV.PackageManager) + err = utils.ExecWithOutput(cwd, utils.GetPackageManager(packageJson.TSDEV.PackageManager, true), "tsc", "--outDir", "dist/src/") + if err != nil { + buildWg.Done() + return err + } + return bundleDts(cwd, name) +} + +func bundleDts(cwd string, name string) error { + + if _, err := os.Stat(types.BUNDLE_DTS_PATH); errors.Is(err, os.ErrNotExist) { + + if _, err := os.Stat("./" + types.BUNDLE_BACKUP_DTS_PATH); errors.Is(err, os.ErrNotExist) { + fmt.Println("[WARN] You can only use --dts flag if you have installed tsdev as a dependency. Error:", err) + return errors.New("cannot find bundle-dts path") + } + utils.ExecWithOutput(cwd, "node", types.BUNDLE_BACKUP_DTS_PATH, "--name", name, "--main", "dist/src/index.d.ts", "--out", "../index.d.ts") + buildWg.Done() + return nil + } + + utils.ExecWithOutput(cwd, "node", types.BUNDLE_DTS_PATH, "--name", name, "--main", "dist/src/index.d.ts", "--out", "../index.d.ts") + buildWg.Done() + return nil +} + +func RunDts() error { + + cwd, err := os.Getwd() + + utils.CheckErr(err) + name, err := utils.GetName() + utils.CheckErr(err) + buildWg.Add(1) + + go EmitDts(cwd, name) + + buildWg.Wait() + return nil +} diff --git a/internal/commands/prettier.go b/internal/commands/prettier.go index c609074..c9dba2f 100644 --- a/internal/commands/prettier.go +++ b/internal/commands/prettier.go @@ -8,7 +8,16 @@ import ( "os" ) -func HandlePrettierCommand() error { +func handlePrettyAll() error { + + return nil +} + +func HandlePrettierCommand(allFlag bool) error { + + if allFlag { + return handlePrettyAll() + } if _, err := os.Stat(types.PRETTY_QUICK_PATH); errors.Is(err, os.ErrNotExist) { diff --git a/internal/utils/packageManger.go b/internal/utils/packageManger.go new file mode 100644 index 0000000..b828f83 --- /dev/null +++ b/internal/utils/packageManger.go @@ -0,0 +1,33 @@ +package utils + +import "internal/types" + +func GetPackageManager(packageManger types.PackageManagerType, run bool) string { + + switch packageManger { + case types.Pnpm: + { + return "pnpm" + } + case types.Yarn: + { + return "yarn" + } + case types.Npm: + { + // npm run cannot run node modules, the way yarn or pnpm can + if run { + return "yarn" + } + return "npm" + } + default: + { + // npm run cannot run node modules, the way yarn or pnpm can + if run { + return "yarn" + } + return "npm" + } + } +}