From b7019a20a309bc52c07eeacefb692894e4113c47 Mon Sep 17 00:00:00 2001 From: Nazar Kornienko Date: Tue, 24 Sep 2024 17:18:32 +0200 Subject: [PATCH] add new features, bun, global run --- .vscode/extensions.json | 23 + .vscode/launch.json | 74 + .vscode/settings.json | 454 ++ README.md | 171 +- biome.json | 131 +- bun.lockb | Bin 0 -> 536732 bytes eslint.config.js | 2485 +++++- knip.json | 36 +- package.json | 117 +- pnpm-lock.yaml | 7127 ----------------- reliverse.config.ts | 53 + src/app.ts | 233 + src/cli/buildRelivator.ts | 98 + src/cli/cloneLibraryTool.ts | 88 + .../{create.test.ts => createProject.test.ts} | 0 src/cli/createProject.ts | 30 + src/cli/installer.ts | 84 + src/cli/justInstallRelivator.ts | 27 + src/constants/metadata.ts | 15 + src/constants/products.ts | 218 + src/index.ts | 2 +- src/relimter/checkAndDownloadFiles.ts | 106 + src/relimter/conflictHandlers.ts | 74 + src/relimter/fileCategories.ts | 12 + src/relimter/fileUtils.ts | 20 + src/relimter/gitOperations.ts | 95 + src/setup/configure.ts | 153 + src/setup/prompt/appts.ts | 224 + src/setup/prompt/biome.ts | 72 + src/setup/prompt/env.ts | 210 + src/setup/prompt/envjs.ts | 105 + src/setup/prompt/eslint.ts | 99 + src/setup/prompt/knip.ts | 72 + src/setup/prompt/nextjs.ts | 114 + src/setup/prompt/putout.ts | 75 + src/setup/types.ts | 39 + src/types/nav.ts | 34 + src/types/string.ts | 14 + src/types/with.ts | 34 + src/utils/fs.ts | 2 +- src/utils/git.ts | 46 + src/{cli/create.ts => utils/prompt.ts} | 168 +- src/utils/validate.ts | 11 +- tsconfig.json | 32 +- tsup.config.ts | 6 +- 45 files changed, 5948 insertions(+), 7335 deletions(-) create mode 100644 .vscode/extensions.json create mode 100644 .vscode/launch.json create mode 100644 .vscode/settings.json create mode 100644 bun.lockb delete mode 100644 pnpm-lock.yaml create mode 100644 reliverse.config.ts create mode 100644 src/app.ts create mode 100644 src/cli/buildRelivator.ts create mode 100644 src/cli/cloneLibraryTool.ts rename src/cli/{create.test.ts => createProject.test.ts} (100%) create mode 100644 src/cli/createProject.ts create mode 100644 src/cli/installer.ts create mode 100644 src/cli/justInstallRelivator.ts create mode 100644 src/constants/metadata.ts create mode 100644 src/constants/products.ts create mode 100644 src/relimter/checkAndDownloadFiles.ts create mode 100644 src/relimter/conflictHandlers.ts create mode 100644 src/relimter/fileCategories.ts create mode 100644 src/relimter/fileUtils.ts create mode 100644 src/relimter/gitOperations.ts create mode 100644 src/setup/configure.ts create mode 100644 src/setup/prompt/appts.ts create mode 100644 src/setup/prompt/biome.ts create mode 100644 src/setup/prompt/env.ts create mode 100644 src/setup/prompt/envjs.ts create mode 100644 src/setup/prompt/eslint.ts create mode 100644 src/setup/prompt/knip.ts create mode 100644 src/setup/prompt/nextjs.ts create mode 100644 src/setup/prompt/putout.ts create mode 100644 src/setup/types.ts create mode 100644 src/types/nav.ts create mode 100644 src/types/string.ts create mode 100644 src/types/with.ts create mode 100644 src/utils/git.ts rename src/{cli/create.ts => utils/prompt.ts} (50%) diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..65d46c9 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,23 @@ +{ + "recommendations": [ + "aaron-bond.better-comments", + "astro-build.houston", + "biomejs.biome", + "bradlc.vscode-tailwindcss", + "charliermarsh.ruff", + "chunsen.bracket-select", + "davidanson.vscode-markdownlint", + "dbaeumer.vscode-eslint", + "fabiospampinato.vscode-open-multiple-files", + "github.github-vscode-theme", + "lokalise.i18n-ally", + "mikekscholz.pop-icon-theme", + "ms-python.python", + "neptunedesign.vs-sequential-number", + "streetsidesoftware.code-spell-checker", + "unifiedjs.vscode-mdx", + "usernamehw.errorlens", + "usernamehw.remove-empty-lines", + "yzhang.markdown-all-in-one" + ] +} diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..6acd833 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,74 @@ +{ + "compounds": [ + { + "configurations": ["Launch Next.js"], + "name": "Launch Next.js" + }, + { + "configurations": ["Launch Next.js", "Launch Next.js in Chrome"], + "name": "Launch Next.js and Chrome" + } + ], + "configurations": [ + { + "name": "Attach by Process ID", + "processId": "${command:PickProcess}", + "request": "attach", + "restart": true, + "type": "node" + }, + { + "console": "internalConsole", + "env": { + "NODE_OPTIONS": "--inspect" + }, + "name": "Launch Next.js", + "program": "${workspaceFolder}/node_modules/next/dist/bin/next", + "request": "launch", + "sourceMaps": true, + "trace": true, + "type": "node" + }, + { + "name": "Launch Next.js in Chrome", + "request": "launch", + "type": "chrome", + "url": "http://localhost:3000", + "webRoot": "${workspaceFolder}" + }, + { + "args": ["--runInBand"], + "envFile": "${workspaceFolder}/.env", + "name": "Launch All Jest Tests", + "program": "${workspaceFolder}/node_modules/jest/bin/jest", + "request": "launch", + "type": "node" + }, + { + "args": ["${relativeFile}"], + "console": "internalConsole", + "internalConsoleOptions": "openOnSessionStart", + "name": "Launch Current Jest Test", + "program": "${workspaceFolder}/node_modules/jest/bin/jest", + "request": "launch", + "type": "node" + }, + { + "console": "integratedTerminal", + "env": { + "NODE_OPTIONS": "--loader=tsx" + }, + "name": "Launch Ava Test (experimental)", + "outputCapture": "std", + "program": "${workspaceFolder}/node_modules/ava/entrypoints/cli.js", + "request": "launch", + "runtimeArgs": ["${file}", "--break", "debug"], + "runtimeExecutable": "${workspaceFolder}/node_modules/.bin/ava", + "runtimeVersion": "20.10.0", + "skipFiles": ["/**/*.js"], + "type": "node" + } + ], + "type": "commonjs", + "version": "0.2.0" +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..41eeb3c --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,454 @@ +{ + "[appts.reliverse]": { + "vscodePreset": "default" + }, + "[css]": { + "editor.defaultFormatter": "vscode.css-language-features" + }, + "[html]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "[javascript]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[javascriptreact]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[json]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[json5]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[jsonc]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[markdown]": { + "editor.defaultFormatter": "DavidAnson.vscode-markdownlint" + }, + "[mdx]": { + "editor.wordWrap": "on" + }, + "[python]": { + "editor.codeActionsOnSave": { + "source.fixAll": "explicit", + "source.organizeImports": "explicit" + }, + "editor.defaultFormatter": "charliermarsh.ruff", + "editor.formatOnSave": true + }, + "[typescript]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[typescriptreact]": { + "editor.defaultFormatter": "biomejs.biome" + }, + "[yaml]": { + "editor.defaultFormatter": "redhat.vscode-yaml" + }, + "biome.enabled": true, + "breadcrumbs.enabled": true, + "cSpell.enabled": true, + "cSpell.userWords": [ + "Menlo", + "Monaspace", + "astro", + "biomejs", + "dotjs", + "mjml", + "pwsh", + "quickfix", + "rgba", + "tson" + ], + "cSpell.words": ["callout", "combobox", "reliverse", "utapi"], + "css.lint.important": "ignore", + "css.lint.unknownAtRules": "ignore", + "debug.toolBarLocation": "docked", + "diffEditor.experimental.showMoves": true, + "diffEditor.hideUnchangedRegions.enabled": true, + "editor.acceptSuggestionOnCommitCharacter": true, + "editor.acceptSuggestionOnEnter": "on", + "editor.bracketPairColorization.enabled": true, + "editor.bracketPairColorization.independentColorPoolPerBracketType": true, + "editor.codeActionsOnSave": { + "quickfix.biome": "explicit", + "source.addMissingImports": "never", + "source.fixAll": "never", + "source.fixAll.eslint": "explicit", + "source.organizeImports": "never", + "source.organizeImports.biome": "never", + "source.removeUnused": "never" + }, + "editor.colorDecorators": true, + "editor.cursorBlinking": "phase", + "editor.cursorSmoothCaretAnimation": "on", + "editor.cursorStyle": "line", + "editor.defaultFormatter": "biomejs.biome", + "editor.detectIndentation": false, + "editor.formatOnPaste": false, + "editor.formatOnSave": true, + "editor.formatOnSaveMode": "file", + "editor.formatOnType": false, + "editor.guides.bracketPairs": true, + "editor.guides.indentation": false, + "editor.hideCursorInOverviewRuler": false, + "editor.inlayHints.enabled": "offUnlessPressed", + "editor.inlineSuggest.enabled": true, + "editor.inlineSuggest.showToolbar": "always", + "editor.insertSpaces": true, + "editor.linkedEditing": true, + "editor.minimap.autohide": false, + "editor.minimap.enabled": true, + "editor.minimap.renderCharacters": false, + "editor.multiCursorModifier": "alt", + "editor.parameterHints.enabled": true, + "editor.quickSuggestions": { + "comments": true, + "other": true, + "strings": true + }, + "editor.quickSuggestionsDelay": 10, + "editor.rulers": [54, 74, 119], + "editor.smoothScrolling": true, + "editor.snippets.codeActions.enabled": true, + "editor.stickyScroll.enabled": true, + "editor.suggest.insertMode": "insert", + "editor.suggest.localityBonus": true, + "editor.suggestOnTriggerCharacters": true, + "editor.suggestSelection": "first", + "editor.tabCompletion": "off", + "editor.tabSize": 2, + "editor.tokenColorCustomizations": { + "comments": "#746f68" + }, + "editor.unicodeHighlight.allowedCharacters": { + "a": true, + "І": true, + "А": true, + "В": true, + "Е": true, + "З": true, + "Н": true, + "О": true, + "Р": true, + "С": true, + "Т": true, + "У": true, + "а": true, + "б": true, + "г": true, + "е": true, + "з": true, + "н": true, + "о": true, + "р": true, + "с": true, + "у": true, + "і": true, + "ا": true, + "ه": true, + "–": true + }, + "editor.unicodeHighlight.allowedLocales": { + "tr": true + }, + "editor.wordBasedSuggestions": "currentDocument", + "eslint.codeActionsOnSave.mode": "problems", + "eslint.enable": true, + "eslint.format.enable": true, + "eslint.ignoreUntitled": true, + "eslint.lintTask.enable": true, + "eslint.lintTask.options": ".", + "eslint.probe": [ + "MDX", + "astro", + "github-actions-workflow", + "html", + "javascript", + "javascriptreact", + "json", + "json5", + "jsonc", + "markdown", + "toml", + "typescript", + "typescriptreact", + "yaml" + ], + "eslint.rules.customizations": [ + { + "rule": "@stylistic/*", + "severity": "off" + }, + { + "rule": "perfectionist/*", + "severity": "off" + }, + { + "rule": "@typescript-eslint/consistent-type-imports", + "severity": "info" + }, + { + "rule": "import-x/newline-after-import", + "severity": "info" + }, + { + "rule": "readable-tailwind/*", + "severity": "info" + }, + { + "rule": "curly", + "severity": "info" + }, + { + "rule": "no-lonely-if", + "severity": "info" + }, + { + "rule": "@stylistic/linebreak-style", + "severity": "info" + }, + { + "rule": "jsonc/indent", + "severity": "info" + }, + { + "rule": "RULES-BELOW-ARE-NOT-AUTOFIXABLE", + "severity": "warn" + }, + { + "rule": "@typescript-eslint/no-unused-vars", + "severity": "warn" + }, + { + "rule": "@stylistic/no-tabs", + "severity": "error" + }, + { + "rule": "@stylistic/no-mixed-spaces-and-tabs", + "severity": "error" + }, + { + "rule": "@stylistic/no-mixed-operators", + "severity": "error" + }, + { + "rule": "@stylistic/max-statements-per-line", + "severity": "error" + }, + { + "rule": "@stylistic/max-len", + "severity": "error" + }, + { + "rule": "@stylistic/line-comment-position", + "severity": "error" + }, + { + "rule": "@stylistic/jsx-pascal-case", + "severity": "error" + }, + { + "rule": "@stylistic/jsx-child-element-spacing", + "severity": "error" + } + ], + "eslint.timeBudget.onFixes": { + "error": 25000, + "warn": 25000 + }, + "eslint.timeBudget.onValidation": { + "error": 25000, + "warn": 25000 + }, + "eslint.validate": [ + "MDX", + "astro", + "github-actions-workflow", + "html", + "javascript", + "javascriptreact", + "json", + "json5", + "jsonc", + "markdown", + "toml", + "typescript", + "typescriptreact", + "yaml" + ], + "extensions.ignoreRecommendations": false, + "files.associations": { + "*.json": "json", + "*.mdx": "mdx", + "*.toml": "properties", + "*.txt": "plaintext", + ".env.example": "properties" + }, + "files.eol": "\n", + "files.insertFinalNewline": true, + "files.trimTrailingWhitespace": true, + "git.autofetch": true, + "git.confirmSync": false, + "git.enableSmartCommit": true, + "git.openRepositoryInParentFolders": "never", + "html.format.indentInnerHtml": true, + "i18n-ally.displayLanguage": "en-US", + "i18n-ally.enabledFrameworks": ["general", "next-intl", "react"], + "i18n-ally.keysInUse": [ + "Manifest.name", + "faq.1.details", + "faq.1.summary", + "faq.2.details", + "faq.2.summary", + "faq.3.details", + "faq.3.summary", + "name" + ], + "i18n-ally.keystyle": "nested", + "i18n-ally.localesPaths": ["messages/default"], + "i18n-ally.sourceLanguage": "en-US", + "javascript.format.semicolons": "insert", + "javascript.inlayHints.enumMemberValues.enabled": true, + "javascript.inlayHints.functionLikeReturnTypes.enabled": true, + "javascript.inlayHints.parameterNames.enabled": "all", + "javascript.inlayHints.parameterTypes.enabled": true, + "javascript.preferences.importModuleSpecifier": "non-relative", + "javascript.updateImportsOnFileMove.enabled": "always", + "json.validate.enable": false, + "markdown.extension.preview.autoShowPreviewToSide": false, + "markdown.preview.scrollEditorWithPreview": true, + "markdown.preview.scrollPreviewWithEditor": true, + "markdownlint.config": { + "MD033": false, + "MD041": false + }, + "mdx.server.enable": true, + "openMultipleFiles.exclude": [ + "**/*.gif", + "**/*.jpeg", + "**/*.png", + "**/*.svg", + "**/*.txt", + "**/.git", + "**/.idea", + "**/.million", + "**/.next", + "**/.nyc_output", + "**/.pnp.*", + "**/.turbo", + "**/.venv", + "**/.yarn", + "**/build", + "**/cluster/deprecated", + "**/coverage", + "**/dist", + "**/dist-dev", + "**/fixture", + "**/node_modules", + "**/package-lock.json", + "**/public", + "**/target", + "**/yarn.lock", + "**/yarn-error.log", + "addons/.output" + ], + "openMultipleFiles.ignore": [".gitignore"], + "openMultipleFiles.limit": 1000, + "outline.problems.badges": false, + "prettify-ts.viewNestedTypes": true, + "problems.defaultViewMode": "table", + "problems.showCurrentInStatus": true, + "problems.sortOrder": "position", + "ruff.lineLength": 88, + "ruff.nativeServer": true, + "search.exclude": { + "**/*.lock": true, + "**/.eslintcache": true, + "**/.idea": true, + "**/.next": true, + "**/.pnp.*": true, + "**/.venv": true, + "**/.yarn": true, + "**/build": true, + "**/dist": true, + "**/next-env.d.ts": true, + "**/package-lock.json": true, + "**/pnpm-lock.yaml": true, + "**/reset.d.ts": true, + "**/tsconfig.tsbuildinfo": true, + "**/yarn-error.log": true + }, + "search.useIgnoreFiles": false, + "tailwindCSS.classAttributes": ["class", "className", "classNames"], + "tailwindCSS.experimental.classRegex": [ + ["(?:'|\"|`)([^']*)(?:'|\"|`)", "cx\\(([^)]*)\\)"], + ["[\"'`]([^\"'`]*).*?[\"'`]", "cva\\(([^)]*)\\)"] + ], + "terminal.integrated.allowedLinkSchemes": [ + "C", + "file", + "http", + "https", + "mailto", + "vscode", + "vscode-insiders" + ], + "terminal.integrated.smoothScrolling": true, + "totalTypeScript.hideAllTips": true, + "totalTypeScript.hideBasicTips": true, + "tsEssentialPlugins.arrayMethodsSnippets.enable": true, + "tsEssentialPlugins.fixSuggestionsSorting": true, + "tsEssentialPlugins.globalLibCompletions.action": "mark", + "tsEssentialPlugins.jsxEmmet.modernize": true, + "tsEssentialPlugins.outline.arraysTuplesNumberedItems": true, + "tsEssentialPlugins.patchOutline": true, + "tsEssentialPlugins.renameImportNameOfFileRename": true, + "tsEssentialPlugins.signatureHelp.excludeBlockScope": true, + "tsEssentialPlugins.skipNodeModulesReferences": true, + "tsEssentialPlugins.suggestions.localityBonus": true, + "tsEssentialPlugins.tupleHelpSignature": true, + "typescript.enablePromptUseWorkspaceTsdk": true, + "typescript.format.semicolons": "insert", + "typescript.inlayHints.enumMemberValues.enabled": true, + "typescript.inlayHints.parameterNames.enabled": "all", + "typescript.preferences.autoImportFileExcludePatterns": [ + "next/dist/client/router.d.ts", + "next/router.d.ts" + ], + "typescript.preferences.importModuleSpecifier": "non-relative", + "typescript.preferences.includePackageJsonAutoImports": "on", + "typescript.referencesCodeLens.enabled": true, + "typescript.reportStyleChecksAsWarnings": true, + "typescript.tsdk": "node_modules/typescript/lib", + "typescript.updateImportsOnFileMove.enabled": "always", + "typescript.validate.enable": true, + "window.autoDetectColorScheme": true, + "window.commandCenter": true, + "window.title": "${dirty}${folderName}${separator}${activeEditorMedium}", + "workbench.colorCustomizations": { + "terminal.ansiBlack": "#21222c", + "terminal.ansiBlue": "#bd93f9", + "terminal.ansiBrightBlack": "#8d92ff", + "terminal.ansiBrightBlue": "#bd93f9", + "terminal.ansiBrightCyan": "#2cccff", + "terminal.ansiBrightGreen": "#20E3B2", + "terminal.ansiBrightMagenta": "#ff6bcb", + "terminal.ansiBrightRed": "#ff7979", + "terminal.ansiBrightWhite": "#ffffff", + "terminal.ansiBrightYellow": "#EAC394", + "terminal.ansiCyan": "#8be9fd", + "terminal.ansiGreen": "#20e3b2", + "terminal.ansiMagenta": "#ff6bcb", + "terminal.ansiRed": "#ff5555", + "terminal.ansiWhite": "#f8f8f2", + "terminal.ansiYellow": "#fde181", + "terminalCursor.background": "#868690", + "terminalCursor.foreground": "#43444D" + }, + "workbench.editor.enablePreview": false, + "workbench.layoutControl.enabled": true, + "workbench.panel.defaultLocation": "bottom", + "workbench.statusBar.visible": true +} diff --git a/README.md b/README.md index 6969ec5..2e85682 100644 --- a/README.md +++ b/README.md @@ -2,39 +2,178 @@ *Build the Sites. Build the Apps. Build the Games. Build Anything.* +**Reliverse CLI**, or simply **Reliverse**, is a command-line tool designed to streamline the setup and configuration of JavaScript/TypeScript projects (for now), with a focus on React and Next.js templates. It allows you to effortlessly bootstrap projects, including the [Relivator Next.js template](https://github.com/blefnk/relivator-nextjs-template), or any other template from GitHub. Reliverse also assists in managing configuration files and resolving potential conflicts between different tools like ESLint, Prettier, and Biome. + ## TL;DR -At its current stage, Reliverse CLI is a powerful website builder right in your terminal. You can start from scratch or with a template, setting everything up automatically or customizing it to your exact preferences. With all the tools pre-configured and ready to go, you can build exactly what you envision. +**It's a single tool for everything.** At its current stage, Reliverse CLI is a powerful CLI website builder, means project bootstrapper, right in your terminal. But it's not going to be just a website builder in the future. And even already you can start from scratch or with a template, setting everything up automatically or customizing it to your exact preferences. With all the tools pre-configured and ready to go, you can build exactly what you envision. + +Remember the feeling of empowerment when you first used a website builder like WordPress? It gave you the freedom to create. But eventually, you hit limits—PageSpeed Insights flagged issues, the performance lagged, and the bloated size of your site became hard to ignore. + +*That’s where Reliverse comes in.* Reliverse is designed to fix the problems of traditional website builders, offering a universal toolset that lets you create anything you can imagine—efficiently and with ease. ## Get Started -**Prerequisites**: +Reliverse is still in its early stages, but it already allows you to bootstrap websites quickly. Soon, advanced customization options will be available, along with game-building tools and other exciting features. You're going to love what's coming. + +By the way, you might imagine that a CLI doing so many things would become bloated, like an elephant in the room, but don’t worry—it’s going to be lean. This is the dream of a creator, a dream that must become reality. Everything has to be perfect. + +*Psst... We’re already working on a frontend version of the builder too!* 😉 + +## Installation + +You should install [Git](https://git-scm.com), [VSCode](https://code.visualstudio.com), and [Node.js LTS](https://nodejs.org/en/download/package-manager) first, then use: -- [Node.js](https://nodejs.org/en/download/package-manager) -- [bun](https://bun.sh) or [pnpm](https://pnpm.io/installation#using-corepack) +- [bun](https://bun.sh) i -g reliverse +- or: [pnpm](https://pnpm.io/installation#using-corepack) add -g reliverse +- or: [yarn](https://yarnpkg.com) global add reliverse +- or: [npm](https://nodejs.org/en/learn/getting-started/an-introduction-to-the-npm-package-manager) i -g reliverse -**Installation**: +## Usage + +Once installed, you can use **Reliverse CLI** to create new projects or manage existing ones. Navigate to the root of your desired directory and run: ```bash -bun i -g reliverse -# or -pnpm i -g reliverse +reliverse ``` -**Usage**: +## Features + +- **Create Projects**: Build new projects from scratch, including your own version of **Relivator Next.js template**, or install any other templates from GitHub. +- **Support for JavaScript/TypeScript Projects**: Primarily designed for React and Next.js projects, but works with other JavaScript/TypeScript libraries as well. +- **Automatic Configuration Management**: Handles project configuration, including ESLint, Biome, Putout, GitHub, and IDE settings. +- **Conflict Resolution**: Detects existing configurations and helps resolve file conflicts, giving you control over which files to keep or replace. +- **Interactive Prompts**: Customize your setup through interactive prompts that allow you to select which file categories to include. +- **Template-Driven**: Automatically clones and installs templates from GitHub to kickstart your development. +- **Unlimited possibilities**: It can work not only with templates! Are you going to clone a JS library? Feel free to use Reliverse! +- **Anything else?!**: Currently, the CLI is optimized for JS/TS projects (like React, Astro, Vue, Svelte, etc.). But in the future, it will be able to work even with native video game applications! This is the dream of Reliverse's founder–a single tool designed for everything–for anything! + +### Commands + +The Reliverse CLI provides a series of interactive prompts to guide you through the project setup: + +1. **Create a New Project**: Build from scratch or use predefined templates. +2. **Install GitHub Templates**: Install any JavaScript/TypeScript project by providing a GitHub repository URL. +3. **Manage Configurations**: The CLI checks for existing configuration files and assists you in handling any conflicts. +4. **File Categories**: You can select from a variety of configuration categories for your project setup, such as ESLint, Biome, Putout, GitHub settings, and IDE preferences. +5. **Post-editing**: Reliverse never leaves you, if you wish it to. It holds your hand throughout your entire development journey. That's why you can run `reliverse` even in an already installed project. If your project's `package.json` contains an `appts` script, that's also a local piece of `reliverse` within your project. + +### Example Workflow + +Here’s an example session of using **Reliverse CLI**: ```bash -reliverse +$ reliverse + +? How do you want to proceed? + 1. I want to build my own Relivator from scratch + 2. I just want to install a template from GitHub + +? Select the file categories you want to download: + ◉ eslint, biome, putout + ◉ GitHub + ◉ IDE + ◉ Reliverse configs + +? Do you want to replace all existing files? (N opens Conflict Management menu) (y/N) ``` -## A Website Builder for the Modern Age +## Configuration Categories -Remember the feeling of empowerment when you first used a website builder like WordPress? It gave you the freedom to create. But eventually, you hit limits—PageSpeed Insights flagged issues, the performance lagged, and the bloated size of your site became hard to ignore. +When setting up a project, you can choose from the following file categories: -*That’s where Reliverse comes in.* Reliverse is designed to fix the problems of traditional website builders, offering a universal toolset that lets you create anything you can imagine—efficiently and with ease. +1. **eslint, biome, putout** + - `.eslintrc.js`, `biome.json`, `.putout.json` +2. **GitHub** + - `.github`, `README.md` +3. **IDE** + - `.vscode` +4. **Reliverse configs** + - `reliverse.config.ts`, `reliverse.info.ts` -Reliverse is still in its early stages, but it already allows you to bootstrap websites quickly. Soon, advanced customization options will be available, along with game-building tools and other exciting features. You're going to love what's coming. +## Conflict Management -By the way, you might imagine that a CLI doing so many things would become bloated, like an elephant in the room, but don’t worry—it’s going to be lean. This is the dream of a creator, a dream that must become reality. Everything has to be perfect. +**Reliverse CLI** helps you handle configuration conflicts for existing files such as `.eslintrc.cjs` or `prettier.config.js`. It prompts you with options to: -*Psst... We’re already working on a frontend version of the builder too!* 😉 +- **Remove**: Delete the existing file. +- **Rename**: Rename the file (e.g., add `.txt` to disable it). +- **Do nothing**: Keep the existing file. + +### Conflict Example + +```bash +? .eslintrc.cjs file exists. Do you want to remove or rename it? + 1. Remove + 2. Rename to .eslintrc.cjs.txt + 3. Do nothing +``` + +### Prettier Conflict Example + +```bash +? prettier.config.js found. Biome will be installed, so Prettier is not necessary. + 1. Remove + 2. Rename to prettier.config.js.txt + 3. Do nothing +``` + +## Installing Other Templates + +You can install any JavaScript/TypeScript project (it is not limited to e.g. Next.js templates, it can be anything, even js libs) from a GitHub repository by providing the repository URL during the interactive setup: + +```bash +$ reliverse + +? How do you want to proceed? + 1. I want to build my own Relivator from scratch + 2. I just want to install a template from GitHub + 3. I want to clone a library/tool from the GitHub + +? Enter the GitHub repository link: (e.g., `https://github.com/user/repo`) +``` + +Reliverse will then clone the repository and set up the project. + +## Development + +### Clone the Repository + +#### Reliverse's Methond + +Just use Reliverse itself to install Reliverse locally 😄 + +Visit [Installation](#installation) section and choose `Tools Installation` when select `Clone Reliverse Repository for Local Development`. + +#### Classical Method + +To contribute to **Reliverse CLI**, you can clone the repository and install the dependencies: + +```bash +git clone https://github.com/reliverse/cli.git +cd reliverse +bun i # OR pnpm i OR yarn install OR npm i +``` + +### Running Locally + +To run the CLI locally for development purposes, use: + +```bash +bun dev +# or +pnpm dev +# or +yarn dev +# or +npm dev +``` + +## Contributing + +We welcome contributions! Feel free to open issues or submit pull requests. Please make sure your code passes all tests and follows our linting guidelines, by just running `bun appts`, before submitting. + +Reliverse uses a different, non-standard approach compared to other bootstrappers. The author of this project has seen many CLIs that handle project bootstrapping. Many of them are truly cool. But their repositories contain a ton files that are later bundled into a single index.js, which is like the installer wizard. As a result, their repositories are often cluttered with a large number of files. Most of their repositories are so-called monorepos, which also adds to the complexity. In contrast, the reliverse/cli repository downloads specific files from already existing repositories and only copies from its own or generates files when it is really necessary. + +## License + +This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for more details. diff --git a/biome.json b/biome.json index 832b1c9..b7d4a9a 100644 --- a/biome.json +++ b/biome.json @@ -1,5 +1,5 @@ { - "$schema": "https://biomejs.dev/schemas/1.8.3/schema.json", + "$schema": "https://biomejs.dev/schemas/1.9.2/schema.json", "css": { "formatter": { "enabled": false, @@ -10,7 +10,7 @@ "quoteStyle": "double" }, "linter": { - "enabled": true + "enabled": false }, "parser": { "allowWrongLineComments": false, @@ -21,7 +21,21 @@ "attributePosition": "auto", "enabled": true, "formatWithErrors": false, - "ignore": [".astro", "dist", ".venv", "addons/.output", "node_modules"], + "ignore": [ + ".git/", + ".idea/", + ".million/", + ".next/", + ".turbo/", + ".vercel/", + "addons/.output/", + "build/", + "cluster/", + "dist/", + "drizzle/", + "node_modules/", + "public/" + ], "indentStyle": "space", "indentWidth": 2, "lineEnding": "lf", @@ -64,11 +78,118 @@ }, "linter": { "enabled": true, - "ignore": [".astro", "dist", ".venv", "addons/.output", "node_modules"], + "ignore": [ + ".git/", + ".idea/", + ".million/", + ".next/", + ".turbo/", + ".vercel/", + "addons/.output/", + "build/", + "cluster/", + "dist/", + "drizzle/", + "node_modules/", + "public/" + ], "rules": { + "a11y": { + "noAriaHiddenOnFocusable": "off", + "noBlankTarget": "off", + "noNoninteractiveElementToInteractiveRole": "off", + "noRedundantRoles": "off", + "useFocusableInteractive": "off", + "useKeyWithClickEvents": "off", + "useSemanticElements": "off" + }, + "complexity": { + "noBannedTypes": "off", + "noForEach": "off", + "noUselessFragments": "off", + "noUselessLoneBlockStatements": "off", + "useArrowFunction": "off", + "useFlatMap": "off", + "useLiteralKeys": "off", + "useOptionalChain": "off", + "useRegexLiterals": "off", + "useSimpleNumberKeys": "off" + }, + "correctness": { + "noChildrenProp": "off", + "noConstantCondition": "off", + "noEmptyPattern": "off", + "noInvalidConstructorSuper": "off", + "noInvalidNewBuiltin": "off", + "noInvalidUseBeforeDeclaration": "off", + "noPrecisionLoss": "off", + "noRenderReturnValue": "off", + "noStringCaseMismatch": "off", + "noSwitchDeclarations": "off", + "noUndeclaredVariables": "off", + "noUnnecessaryContinue": "off", + "noUnreachable": "off", + "noUnreachableSuper": "off", + "noUnsafeFinally": "off", + "noUnsafeOptionalChaining": "off", + "noUnusedLabels": "off", + "noUnusedPrivateClassMembers": "off", + "noUnusedVariables": "off", + "noVoidElementsWithChildren": "off", + "noVoidTypeReturn": "off", + "useExhaustiveDependencies": "off", + "useHookAtTopLevel": "off", + "useIsNan": "off", + "useValidForDirection": "off", + "useYield": "off" + }, + "performance": { + "noAccumulatingSpread": "off", + "noDelete": "off" + }, "recommended": true, + "security": { + "noDangerouslySetInnerHtml": "off" + }, "style": { - "noInferrableTypes": "off" + "noInferrableTypes": "off", + "noNonNullAssertion": "off", + "noParameterAssign": "off", + "noUselessElse": "off", + "useEnumInitializers": "off", + "useExportType": "off", + "useImportType": "off", + "useNamingConvention": "off", + "useNodejsImportProtocol": "off", + "useNumberNamespace": "off", + "useShorthandFunctionType": "off", + "useWhile": "off" + }, + "suspicious": { + "noApproximativeNumericConstant": "off", + "noArrayIndexKey": "off", + "noAssignInExpressions": "off", + "noCommentText": "off", + "noCompareNegZero": "off", + "noConfusingLabels": "off", + "noConstEnum": "off", + "noDoubleEquals": "off", + "noDuplicateObjectKeys": "off", + "noEmptyInterface": "off", + "noExplicitAny": "off", + "noExtraNonNullAssertion": "off", + "noGlobalIsFinite": "off", + "noGlobalIsNan": "off", + "noImplicitAnyLet": "off", + "noMisleadingCharacterClass": "off", + "noMisrefactoredShorthandAssign": "off", + "noSelfCompare": "off", + "noShadowRestrictedNames": "off", + "noSparseArray": "off", + "noUnsafeNegation": "off", + "useIsArray": "off", + "useNamespaceKeyword": "off", + "useValidTypeof": "off" } } }, diff --git a/bun.lockb b/bun.lockb new file mode 100644 index 0000000000000000000000000000000000000000..8783b4cca7a36f8c286a567251992be5213fb60c GIT binary patch literal 536732 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Ð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