From 264773e51db929c6ad318913aa37951853cebc3b Mon Sep 17 00:00:00 2001 From: winches <329487092@qq.com> Date: Thu, 5 Dec 2024 00:05:13 +0800 Subject: [PATCH 01/10] feat: add command add canary option --- src/actions/add-action.ts | 11 +- src/constants/components.json | 751 ++++++++++++++++++++++++- src/constants/store.ts | 6 + src/helpers/beta.ts | 4 +- src/helpers/canary.ts | 31 + src/helpers/check.ts | 33 +- src/index.ts | 6 +- src/prompts/get-beta-version-select.ts | 4 +- src/scripts/helpers.ts | 90 ++- 9 files changed, 891 insertions(+), 45 deletions(-) create mode 100644 src/helpers/canary.ts diff --git a/src/actions/add-action.ts b/src/actions/add-action.ts index b50c019..5a64d5c 100644 --- a/src/actions/add-action.ts +++ b/src/actions/add-action.ts @@ -6,6 +6,7 @@ import {existsSync, writeFileSync} from 'node:fs'; import chalk from 'chalk'; import {getBetaComponents} from '@helpers/beta'; +import {getCanaryComponents} from '@helpers/canary'; import { checkApp, checkIllegalComponents, @@ -38,6 +39,7 @@ interface AddActionOptions { appPath?: string; addApp?: boolean; beta?: boolean; + canary?: boolean; } export async function addAction(components: string[], options: AddActionOptions) { @@ -46,6 +48,7 @@ export async function addAction(components: string[], options: AddActionOptions) all = false, appPath = findFiles('**/App.(j|t)sx')[0], beta = false, + canary = false, packagePath = resolver('package.json'), tailwindPath = findFiles('**/tailwind.config.(j|t)s')[0] } = options; @@ -117,7 +120,7 @@ export async function addAction(components: string[], options: AddActionOptions) const [, ...missingDependencies] = await checkRequiredContentInstalled( 'all', allDependenciesKeys, - {beta} + {beta, canary} ); if (missingDependencies.length) { @@ -136,11 +139,13 @@ export async function addAction(components: string[], options: AddActionOptions) const [, ..._missingDependencies] = await checkRequiredContentInstalled( 'partial', allDependenciesKeys, - {beta} + {beta, canary} ); const mergedComponents = beta ? await getBetaComponents(components) - : components.map((c) => store.nextUIComponentsMap[c]!.package); + : canary + ? await getCanaryComponents(components) + : components.map((c) => store.nextUIComponentsMap[c]!.package); const missingDependencies = [..._missingDependencies, ...mergedComponents]; Logger.info( diff --git a/src/constants/components.json b/src/constants/components.json index 9cd92cd..704edc4 100644 --- a/src/constants/components.json +++ b/src/constants/components.json @@ -1362,7 +1362,756 @@ "@nextui-org/system": ">=2.3.0-beta.0", "tailwindcss": ">=3.4.0" } + }, + { + "name": "form", + "package": "@nextui-org/form", + "version": "2.0.1", + "docs": "https://nextui.org/docs/components/form", + "description": "A form is a group of inputs that allows users submit data to a server and supports field validation errors.", + "status": "new", + "style": "", + "peerDependencies": { + "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.3.0-beta.0", + "react": ">=18", + "react-dom": ">=18", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "input-otp", + "package": "@nextui-org/input-otp", + "version": "2.0.1", + "docs": "https://nextui.org/docs/components/input-otp", + "description": "", + "status": "new", + "style": "", + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18", + "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.3.0-beta.0", + "tailwindcss": ">=3.4.0" + } + } + ], + "version": "2.4.8", + "canaryComponents": [ + { + "name": "accordion", + "package": "@nextui-org/accordion", + "version": "2.1.0", + "docs": "https://nextui.org/docs/components/accordion", + "description": "Collapse display a list of high-level options that can expand/collapse to reveal more information.", + "status": "stable", + "style": "", + "peerDependencies": { + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1", + "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.3.0-beta.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "alert", + "package": "@nextui-org/alert", + "version": "2.1.0", + "docs": "https://nextui.org/docs/components/alert", + "description": "Alerts are temporary notifications that provide concise feedback about an action or event.", + "status": "new", + "style": "", + "peerDependencies": { + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.3.0-beta.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "autocomplete", + "package": "@nextui-org/autocomplete", + "version": "2.2.0", + "docs": "https://nextui.org/docs/components/autocomplete", + "description": "An autocomplete combines a text input with a listbox, allowing users to filter a list of options to items matching a query.", + "status": "updated", + "style": "", + "peerDependencies": { + "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.3.0-beta.0", + "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1", + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "avatar", + "package": "@nextui-org/avatar", + "version": "2.1.0", + "docs": "https://nextui.org/docs/components/avatar", + "description": "The Avatar component is used to represent a user, and displays the profile picture, initials or fallback icon.", + "status": "stable", + "style": "", + "peerDependencies": { + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.3.0-beta.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "badge", + "package": "@nextui-org/badge", + "version": "2.1.0", + "docs": "https://nextui.org/docs/components/badge", + "description": "Badges are used as a small numerical value or status descriptor for UI elements.", + "status": "stable", + "style": "", + "peerDependencies": { + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.3.0-beta.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "breadcrumbs", + "package": "@nextui-org/breadcrumbs", + "version": "2.1.0", + "docs": "https://nextui.org/docs/components/breadcrumbs", + "description": "Breadcrumbs display a hierarchy of links to the current page or resource in an application.", + "status": "stable", + "style": "", + "peerDependencies": { + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.3.0-beta.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "button", + "package": "@nextui-org/button", + "version": "2.1.0", + "docs": "https://nextui.org/docs/components/button", + "description": "Buttons allow users to perform actions and choose with a single tap.", + "status": "updated", + "style": "", + "peerDependencies": { + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1", + "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.3.0-beta.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "calendar", + "package": "@nextui-org/calendar", + "version": "2.1.0", + "docs": "https://nextui.org/docs/components/calendar", + "description": "A calendar displays one or more date grids and allows users to select a single date.", + "status": "stable", + "style": "", + "peerDependencies": { + "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.3.0-beta.0", + "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1", + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "card", + "package": "@nextui-org/card", + "version": "2.1.0", + "docs": "https://nextui.org/docs/components/card", + "description": "Card is a container for text, photos, and actions in the context of a single subject.", + "status": "stable", + "style": "", + "peerDependencies": { + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1", + "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.3.0-beta.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "checkbox", + "package": "@nextui-org/checkbox", + "version": "2.2.0", + "docs": "https://nextui.org/docs/components/checkbox", + "description": "Checkboxes allow users to select multiple items from a list of individual items, or to mark one individual item as selected.", + "status": "updated", + "style": "", + "peerDependencies": { + "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.3.0-beta.0", + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "chip", + "package": "@nextui-org/chip", + "version": "2.1.0", + "docs": "https://nextui.org/docs/components/chip", + "description": "Chips help people enter information, make selections, filter content, or trigger actions.", + "status": "stable", + "style": "", + "peerDependencies": { + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.3.0-beta.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "code", + "package": "@nextui-org/code", + "version": "2.1.0", + "docs": "https://nextui.org/docs/components/code", + "description": "Code is a component used to display inline code.", + "status": "stable", + "style": "", + "peerDependencies": { + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "@nextui-org/theme": ">=2.3.0-beta.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "date-input", + "package": "@nextui-org/date-input", + "version": "2.2.0", + "docs": "https://nextui.org/docs/components/date-input", + "description": "A date input allows users to enter and edit date and time values using a keyboard.", + "status": "stable", + "style": "", + "peerDependencies": { + "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.3.0-beta.0", + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "date-picker", + "package": "@nextui-org/date-picker", + "version": "2.2.0", + "docs": "https://nextui.org/docs/components/date-picker", + "description": "A date picker combines a DateInput and a Calendar popover to allow users to enter or select a date and time value.", + "status": "stable", + "style": "", + "peerDependencies": { + "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.3.0-beta.0", + "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1", + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "divider", + "package": "@nextui-org/divider", + "version": "2.1.0", + "docs": "https://nextui.org/docs/components/divider", + "description": ". A separator is a visual divider between two groups of content", + "status": "stable", + "style": "", + "peerDependencies": { + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "@nextui-org/theme": ">=2.3.0-beta.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "drawer", + "package": "@nextui-org/drawer", + "version": "2.1.0", + "docs": "https://nextui.org/docs/components/drawer", + "description": "Used to render a content that slides in from the side of the screen.", + "status": "new", + "style": "", + "peerDependencies": { + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.3.0-beta.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "dropdown", + "package": "@nextui-org/dropdown", + "version": "2.2.0", + "docs": "https://nextui.org/docs/components/dropdown", + "description": "A dropdown displays a list of actions or options that a user can choose.", + "status": "stable", + "style": "", + "peerDependencies": { + "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.3.0-beta.0", + "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1", + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "form", + "package": "@nextui-org/form", + "version": "2.0.1", + "docs": "https://nextui.org/docs/components/form", + "description": "A form is a group of inputs that allows users submit data to a server and supports field validation errors.", + "status": "new", + "style": "", + "peerDependencies": { + "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.3.0-beta.0", + "react": ">=18", + "react-dom": ">=18", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "image", + "package": "@nextui-org/image", + "version": "2.1.0", + "docs": "https://nextui.org/docs/components/image", + "description": "A simple image component", + "status": "stable", + "style": "", + "peerDependencies": { + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.3.0-beta.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "input", + "package": "@nextui-org/input", + "version": "2.3.0", + "docs": "https://nextui.org/docs/components/input", + "description": "The input component is designed for capturing user input within a text field.", + "status": "updated", + "style": "", + "peerDependencies": { + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.3.0-beta.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "input-otp", + "package": "@nextui-org/input-otp", + "version": "2.0.1", + "docs": "https://nextui.org/docs/components/input-otp", + "description": "", + "status": "new", + "style": "", + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18", + "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.3.0-beta.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "kbd", + "package": "@nextui-org/kbd", + "version": "2.1.0", + "docs": "https://nextui.org/docs/components/kbd", + "description": "The keyboard key components indicates which key or set of keys used to execute a specificv action", + "status": "stable", + "style": "", + "peerDependencies": { + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "@nextui-org/theme": ">=2.3.0-beta.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "link", + "package": "@nextui-org/link", + "version": "2.1.0", + "docs": "https://nextui.org/docs/components/link", + "description": "Links allow users to click their way from page to page. This component is styled to resemble a hyperlink and semantically renders an <a>", + "status": "stable", + "style": "", + "peerDependencies": { + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.3.0-beta.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "listbox", + "package": "@nextui-org/listbox", + "version": "2.2.0", + "docs": "https://nextui.org/docs/components/listbox", + "description": "A listbox displays a list of options and allows a user to select one or more of them.", + "status": "updated", + "style": "", + "peerDependencies": { + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.3.0-beta.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "menu", + "package": "@nextui-org/menu", + "version": "2.1.0", + "docs": "https://nextui.org/docs/components/menu", + "description": "A menu displays a list of options and allows a user to select one or more of them.", + "status": "stable", + "style": "", + "peerDependencies": { + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.3.0-beta.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "modal", + "package": "@nextui-org/modal", + "version": "2.1.0", + "docs": "https://nextui.org/docs/components/modal", + "description": "Displays a dialog with a custom content that requires attention or provides additional information.", + "status": "updated", + "style": "", + "peerDependencies": { + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1", + "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.3.0-beta.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "navbar", + "package": "@nextui-org/navbar", + "version": "2.1.0", + "docs": "https://nextui.org/docs/components/navbar", + "description": "A responsive navigation header positioned on top side of your page that includes support for branding, links, navigation, collapse and more.", + "status": "stable", + "style": "", + "peerDependencies": { + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1", + "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.3.0-beta.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "pagination", + "package": "@nextui-org/pagination", + "version": "2.1.0", + "docs": "https://nextui.org/docs/components/pagination", + "description": "The Pagination component allows you to display active page and navigate between multiple pages.", + "status": "stable", + "style": "", + "peerDependencies": { + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.3.0-beta.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "popover", + "package": "@nextui-org/popover", + "version": "2.2.0", + "docs": "https://nextui.org/docs/components/popover", + "description": "A popover is an overlay element positioned relative to a trigger.", + "status": "stable", + "style": "", + "peerDependencies": { + "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.3.0-beta.0", + "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1", + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "progress", + "package": "@nextui-org/progress", + "version": "2.1.0", + "docs": "https://nextui.org/docs/components/progress", + "description": "Progress bars show either determinate or indeterminate progress of an operation over time.", + "status": "stable", + "style": "", + "peerDependencies": { + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.3.0-beta.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "radio", + "package": "@nextui-org/radio", + "version": "2.2.0", + "docs": "https://nextui.org/docs/components/radio", + "description": "Radios allow users to select a single option from a list of mutually exclusive options.", + "status": "stable", + "style": "", + "peerDependencies": { + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.3.0-beta.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "ripple", + "package": "@nextui-org/ripple", + "version": "2.1.0", + "docs": "https://nextui.org/docs/components/ripple", + "description": "A simple implementation to display a ripple animation when the source component is clicked", + "status": "stable", + "style": "", + "peerDependencies": { + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1", + "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.3.0-beta.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "scroll-shadow", + "package": "@nextui-org/scroll-shadow", + "version": "2.2.0", + "docs": "https://nextui.org/docs/components/scroll-shadow", + "description": "A component that applies top and bottom shadows when content overflows on scroll.", + "status": "stable", + "style": "", + "peerDependencies": { + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.3.0-beta.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "select", + "package": "@nextui-org/select", + "version": "2.3.0", + "docs": "https://nextui.org/docs/components/select", + "description": "A select displays a collapsible list of options and allows a user to select one of them.", + "status": "updated", + "style": "", + "peerDependencies": { + "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.3.0-beta.0", + "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1", + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "skeleton", + "package": "@nextui-org/skeleton", + "version": "2.1.0", + "docs": "https://nextui.org/docs/components/skeleton", + "description": "Skeleton is used to display the loading state of some component.", + "status": "stable", + "style": "", + "peerDependencies": { + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.3.0-beta.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "slider", + "package": "@nextui-org/slider", + "version": "2.3.0", + "docs": "https://nextui.org/docs/components/slider", + "description": "A slider allows a user to select one or more values within a range.", + "status": "stable", + "style": "", + "peerDependencies": { + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.3.0-beta.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "snippet", + "package": "@nextui-org/snippet", + "version": "2.1.0", + "docs": "https://nextui.org/docs/components/snippet", + "description": "Display a snippet of copyable code for the command line.", + "status": "stable", + "style": "", + "peerDependencies": { + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1", + "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.3.0-beta.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "spacer", + "package": "@nextui-org/spacer", + "version": "2.1.0", + "docs": "https://nextui.org/docs/components/spacer", + "description": "A flexible spacer component designed to create consistent spacing and maintain alignment in your layout.", + "status": "stable", + "style": "", + "peerDependencies": { + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "@nextui-org/theme": ">=2.3.0-beta.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "spinner", + "package": "@nextui-org/spinner", + "version": "2.1.0", + "docs": "https://nextui.org/docs/components/spinner", + "description": "Loaders express an unspecified wait time or display the length of a process.", + "status": "stable", + "style": "", + "peerDependencies": { + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "@nextui-org/theme": ">=2.3.0-beta.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "switch", + "package": "@nextui-org/switch", + "version": "2.1.0", + "docs": "https://nextui.org/docs/components/switch", + "description": "A switch is similar to a checkbox, but represents on/off values as opposed to selection.", + "status": "updated", + "style": "toggle", + "peerDependencies": { + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.3.0-beta.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "table", + "package": "@nextui-org/table", + "version": "2.1.0", + "docs": "https://nextui.org/docs/components/table", + "description": "Tables are used to display tabular data using rows and columns. ", + "status": "stable", + "style": "", + "peerDependencies": { + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.3.0-beta.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "tabs", + "package": "@nextui-org/tabs", + "version": "2.1.0", + "docs": "https://nextui.org/docs/components/tabs", + "description": "Tabs organize content into multiple sections and allow users to navigate between them.", + "status": "stable", + "style": "", + "peerDependencies": { + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1", + "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.3.0-beta.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "tooltip", + "package": "@nextui-org/tooltip", + "version": "2.1.0", + "docs": "https://nextui.org/docs/components/tooltip", + "description": "A React Component for rendering dynamically positioned Tooltips", + "status": "stable", + "style": "popover", + "peerDependencies": { + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1", + "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.3.0-beta.0", + "tailwindcss": ">=3.4.0" + } + }, + { + "name": "user", + "package": "@nextui-org/user", + "version": "2.1.0", + "docs": "https://nextui.org/docs/components/user", + "description": "Flexible User Profile Component.", + "status": "stable", + "style": "", + "peerDependencies": { + "react": ">=18 || >=19.0.0-rc.0", + "react-dom": ">=18 || >=19.0.0-rc.0", + "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.3.0-beta.0", + "tailwindcss": ">=3.4.0" + } } ], - "version": "2.4.8" + "canaryVersion": "0.0.0-canary-20241204130109" } diff --git a/src/constants/store.ts b/src/constants/store.ts index 85afcbd..9aa3f7d 100644 --- a/src/constants/store.ts +++ b/src/constants/store.ts @@ -1,6 +1,7 @@ import type {ExtractStoreData, SAFE_ANY} from '@helpers/type'; import {getBetaVersion} from '@helpers/beta'; +import {getCanaryVersion} from '@helpers/canary'; import {type Components, getLatestVersion} from 'src/scripts/helpers'; import {NEXTUI_CLI, NEXT_UI} from './required'; @@ -12,6 +13,7 @@ export type Store = { cliLatestVersion: string; latestVersion: string; betaVersion: string; + canaryVersion: string; nextUIComponents: Components; nextUIComponentsKeys: string[]; nextUIcomponentsPackages: string[]; @@ -41,6 +43,10 @@ export async function getStore( } else if (key === 'betaVersion') { data = (await getBetaVersion(NEXT_UI)) as SAFE_ANY; + store[key] = data; + } else if (key === 'canaryVersion') { + data = (await getCanaryVersion(NEXT_UI)) as SAFE_ANY; + store[key] = data; } } diff --git a/src/helpers/beta.ts b/src/helpers/beta.ts index 6c49bf7..756a758 100644 --- a/src/helpers/beta.ts +++ b/src/helpers/beta.ts @@ -2,7 +2,7 @@ import {getCacheExecData} from 'src/scripts/cache/cache'; import {Logger} from './logger'; -export async function getBetaVersionData(component: string) { +export async function getPackageVersionData(component: string) { const data = await getCacheExecData( `npm view ${component} dist-tags --json`, `Fetching ${component} tags` @@ -16,7 +16,7 @@ export function getPrefixComponent(component: string) { } export async function getBetaVersion(component: string) { - const data = await getBetaVersionData(component); + const data = await getPackageVersionData(component); try { return JSON.parse(data).beta; diff --git a/src/helpers/canary.ts b/src/helpers/canary.ts new file mode 100644 index 0000000..1cb5070 --- /dev/null +++ b/src/helpers/canary.ts @@ -0,0 +1,31 @@ +import {getPackageVersionData, getPrefixComponent} from './beta'; +import {Logger} from './logger'; + +export async function getCanaryVersion(component: string) { + const data = await getPackageVersionData(component); + + try { + return JSON.parse(data).canary; + } catch (error) { + Logger.error(`Get canary version error: ${error}`); + process.exit(1); + } +} + +/** + * @example Input: ["drawer"] + * + * Return: + * ["@nextui-org/drawer@canary"] + */ +export async function getCanaryComponents(components: string[]) { + const componentsVersionList = await Promise.all( + components.map(getPrefixComponent).map(async (c) => { + const version = await getCanaryVersion(c); + + return `${getPrefixComponent(c)}@${version}`; + }) + ); + + return componentsVersionList; +} diff --git a/src/helpers/check.ts b/src/helpers/check.ts index aa83c45..46bf7aa 100644 --- a/src/helpers/check.ts +++ b/src/helpers/check.ts @@ -22,7 +22,7 @@ import { import {store} from 'src/constants/store'; import {compareVersions} from 'src/scripts/helpers'; -import {getBetaVersionData} from './beta'; +import {getPackageVersionData} from './beta'; import {Logger} from './logger'; import {getMatchArray, getMatchImport} from './match'; import {findMostMatchText} from './math-diff'; @@ -107,6 +107,15 @@ interface CheckPeerDependenciesConfig { allDependencies?: Record; packageNames?: string[]; beta?: boolean; + canary?: boolean; +} + +function getConditionData(beta: boolean, canary: boolean) { + return beta + ? {betaVersion: store.betaVersion, tag: 'beta'} + : canary + ? {canaryVersion: store.canaryVersion, tag: 'canary'} + : null; } /** @@ -124,14 +133,15 @@ export async function checkRequiredContentInstalled< dependenciesKeys: Set, checkPeerDependenciesConfig?: T extends {peerDependencies: infer P} ? P extends true - ? Required> + ? Required> : T : T ): Promise { const result = [] as unknown as CheckResult; - const {allDependencies, beta, packageNames, peerDependencies} = (checkPeerDependenciesConfig ?? - {}) as Required; + const {allDependencies, beta, canary, packageNames, peerDependencies} = + (checkPeerDependenciesConfig ?? {}) as Required; const peerDependenciesList: string[] = []; + const conditionData = getConditionData(beta, canary); if (peerDependencies) { const peerDepList = await checkPeerDependencies({allDependencies, packageNames}); @@ -147,7 +157,8 @@ export async function checkRequiredContentInstalled< if (hasAllComponents && hasFramerMotion && !peerDependenciesList.length) { return [true]; } - !hasAllComponents && result.push(beta ? `${NEXT_UI}@${store.betaVersion}` : NEXT_UI); + !hasAllComponents && + result.push(conditionData ? `${NEXT_UI}@${conditionData.betaVersion}` : NEXT_UI); !hasFramerMotion && result.push(FRAMER_MOTION); !hasTailwind && result.push(TAILWINDCSS); } else if (type === 'partial') { @@ -160,11 +171,15 @@ export async function checkRequiredContentInstalled< return [true]; } !hasFramerMotion && result.push(FRAMER_MOTION); - const betaSystemUI = await getBetaVersionData(SYSTEM_UI); - const betaThemeUI = await getBetaVersionData(THEME_UI); + const conditionSystemUI = JSON.parse(await getPackageVersionData(SYSTEM_UI)); + const conditionThemeUI = JSON.parse(await getPackageVersionData(THEME_UI)); - !hasSystemUI && result.push(beta ? `${SYSTEM_UI}@${betaSystemUI}` : SYSTEM_UI); - !hasThemeUI && result.push(beta ? `${THEME_UI}@${betaThemeUI}` : THEME_UI); + !hasSystemUI && + result.push( + conditionData ? `${SYSTEM_UI}@${conditionSystemUI[conditionData.tag]}` : SYSTEM_UI + ); + !hasThemeUI && + result.push(conditionData ? `${THEME_UI}@${conditionThemeUI[conditionData.tag]}` : THEME_UI); !hasTailwind && result.push(TAILWINDCSS); } diff --git a/src/index.ts b/src/index.ts index c5a5880..c5ff9ac 100644 --- a/src/index.ts +++ b/src/index.ts @@ -100,6 +100,7 @@ nextui .option('--prettier [boolean]', 'Apply Prettier formatting to the added content') .option('--addApp [boolean]', 'Include App.tsx file content that requires a provider', false) .option('-b --beta [boolean]', 'Add beta components', false) + .option('-c --canary [boolean]', 'Add canary components', false) .action(addAction); nextui @@ -150,7 +151,8 @@ nextui.hook('preAction', async (command) => { const options = (command as SAFE_ANY).rawArgs.slice(2); const noCache = options.includes('--no-cache'); const debug = options.includes('--debug') || options.includes('-d'); - // const componentsArgs = command.args?.slice(1); + const beta = options.includes('--beta') || options.includes('-b'); + const canary = options.includes('--canary') || options.includes('-c'); // Init cache initCache(noCache); @@ -159,7 +161,7 @@ nextui.hook('preAction', async (command) => { if (args && commandList.includes(args as CommandName)) { // Before run the command init the components.json - const nextUIComponents = (await getComponents()).components; + const nextUIComponents = (await getComponents({beta, canary})).components; initStoreComponentsData(nextUIComponents); } diff --git a/src/prompts/get-beta-version-select.ts b/src/prompts/get-beta-version-select.ts index 3c29ecd..10177e1 100644 --- a/src/prompts/get-beta-version-select.ts +++ b/src/prompts/get-beta-version-select.ts @@ -1,4 +1,4 @@ -import {getBetaVersionData} from '@helpers/beta'; +import {getPackageVersionData} from '@helpers/beta'; import {getSelect} from './index'; @@ -6,7 +6,7 @@ export async function getBetaVersionSelect(components: string[]) { const result: string[] = []; for (const component of components) { - const betaVersionData = JSON.parse(await getBetaVersionData(component)); + const betaVersionData = JSON.parse(await getPackageVersionData(component)); const selectedResult = await getSelect( `Select beta version of ${component}`, diff --git a/src/scripts/helpers.ts b/src/scripts/helpers.ts index 3276ba4..7e4f41e 100644 --- a/src/scripts/helpers.ts +++ b/src/scripts/helpers.ts @@ -32,8 +32,15 @@ export type ComponentsJson = { components: Components; betaComponents: Components; betaVersion: string; + canaryComponents: Components; + canaryVersion: string; }; +interface UpdateComponentsOptions { + beta?: boolean; + canary?: boolean; +} + /** * Compare two versions * @example compareVersions('1.0.0', '1.0.1') // -1 @@ -51,7 +58,9 @@ export function compareVersions(version1 = '', version2 = '') { } } -export async function updateComponents() { +export async function updateComponents(options?: UpdateComponentsOptions) { + const {beta = false, canary = false} = options ?? {}; + if (!existsSync(COMPONENTS_PATH)) { // First time download the latest date from net await autoUpdateComponents(); @@ -62,22 +71,31 @@ export async function updateComponents() { const components = JSON.parse(readFileSync(COMPONENTS_PATH, 'utf-8')) as ComponentsJson; const currentVersion = components.version; const betaVersion = components.betaVersion; + const canaryVersion = components.canaryVersion; const latestVersion = await getStore('latestVersion'); const latestBetaVersion = await getStore('betaVersion'); + const latestCanaryVersion = await getStore('canaryVersion'); if ( compareVersions(currentVersion, latestVersion) === -1 || - compareVersions(betaVersion, latestBetaVersion) === -1 + (beta && (compareVersions(betaVersion, latestBetaVersion) === -1 || !betaVersion)) || + (canary && (compareVersions(canaryVersion, latestCanaryVersion) === -1 || !canaryVersion)) ) { // After the first time, check the version and update - await autoUpdateComponents(latestVersion, latestBetaVersion); + await autoUpdateComponents({ + beta, + betaVersion: latestBetaVersion, + canary, + canaryVersion: latestCanaryVersion, + latestVersion + }); } } -export async function getComponents() { +export async function getComponents(options?: UpdateComponentsOptions) { let components: ComponentsJson = {} as ComponentsJson; - await updateComponents(); + await updateComponents(options); try { components = JSON.parse(readFileSync(COMPONENTS_PATH, 'utf-8')) as ComponentsJson; @@ -137,31 +155,51 @@ export async function getLatestVersion(packageName: string): Promise { const getUnpkgUrl = (version: string) => `https://unpkg.com/@nextui-org/react@${version}/dist/components.json`; -export async function autoUpdateComponents(latestVersion?: string, betaVersion?: string) { - [latestVersion, betaVersion] = await Promise.all([ - latestVersion || getStore('latestVersion'), - betaVersion || getStore('betaVersion') - ]); - - const url = getUnpkgUrl(latestVersion); - - const [components, betaComponents] = await Promise.all([ - downloadFile(url), - downloadFile(getUnpkgUrl(betaVersion), false) - ]); - - const filterMissingComponents = betaComponents.filter( - (component) => !components.find((c) => c.name === component.name) - ); +export async function autoUpdateComponents( + options: { + latestVersion?: string; + betaVersion?: string; + canaryVersion?: string; + } & UpdateComponentsOptions = {beta: true, canary: true} +) { + let {betaVersion, canaryVersion, latestVersion} = options; + const {beta, canary} = options; + + [latestVersion, betaVersion, canaryVersion] = await Promise.all([ + !beta && !canary && (latestVersion || getStore('latestVersion')), + beta && (betaVersion || getStore('betaVersion')), + canary && (canaryVersion || getStore('canaryVersion')) + ] as string[]); + + const [components, betaComponents, canaryComponents] = await Promise.all([ + latestVersion ? downloadFile(getUnpkgUrl(latestVersion)) : [], + betaVersion ? downloadFile(getUnpkgUrl(betaVersion)) : [], + canaryVersion ? downloadFile(getUnpkgUrl(canaryVersion)) : [] + ] as Components[]); + + const originalComponentsJson = JSON.parse( + readFileSync(COMPONENTS_PATH, 'utf-8') + ) as ComponentsJson; + + const filterMissingComponents = beta + ? betaComponents?.filter( + (component) => !originalComponentsJson.components?.find((c) => c.name === component.name) + ) + : canary + ? canaryComponents?.filter( + (component) => !originalComponentsJson.components?.find((c) => c.name === component.name) + ) + : []; // Add missing beta components to components - components.push(...filterMissingComponents); + components?.push(...(filterMissingComponents ?? [])); const componentsJson: ComponentsJson = { - betaComponents, - betaVersion, - components, - version: latestVersion + ...originalComponentsJson, + ...(beta ? {betaComponents, betaVersion} : {}), + ...(canary ? {canaryComponents, canaryVersion} : {}), + ...(latestVersion ? {version: latestVersion} : {}), + components: originalComponentsJson.components.concat(filterMissingComponents ?? []) }; writeFileSync(COMPONENTS_PATH, JSON.stringify(componentsJson, null, 2), 'utf-8'); From 4dc65d8fb5cc180d8c943c89f5c0d1dc277959d9 Mon Sep 17 00:00:00 2001 From: winches <329487092@qq.com> Date: Thu, 5 Dec 2024 21:34:19 +0800 Subject: [PATCH 02/10] fix: version --- src/helpers/check.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/helpers/check.ts b/src/helpers/check.ts index 46bf7aa..e2a35ba 100644 --- a/src/helpers/check.ts +++ b/src/helpers/check.ts @@ -112,9 +112,9 @@ interface CheckPeerDependenciesConfig { function getConditionData(beta: boolean, canary: boolean) { return beta - ? {betaVersion: store.betaVersion, tag: 'beta'} + ? {tag: 'beta', version: store.betaVersion} : canary - ? {canaryVersion: store.canaryVersion, tag: 'canary'} + ? {tag: 'canary', version: store.canaryVersion} : null; } @@ -158,7 +158,7 @@ export async function checkRequiredContentInstalled< return [true]; } !hasAllComponents && - result.push(conditionData ? `${NEXT_UI}@${conditionData.betaVersion}` : NEXT_UI); + result.push(conditionData ? `${NEXT_UI}@${conditionData.version}` : NEXT_UI); !hasFramerMotion && result.push(FRAMER_MOTION); !hasTailwind && result.push(TAILWINDCSS); } else if (type === 'partial') { From cca8220551f22c84c10eb34e86ab5689247802a1 Mon Sep 17 00:00:00 2001 From: winches <329487092@qq.com> Date: Thu, 5 Dec 2024 23:01:10 +0800 Subject: [PATCH 03/10] feat: upgrade command support canary --- package.json | 2 +- pnpm-lock.yaml | 10 +-- src/actions/upgrade-action.ts | 31 +++++-- src/constants/components.json | 150 +++++++++++++++++++++------------- src/constants/store.ts | 2 + src/helpers/upgrade.ts | 10 ++- src/index.ts | 3 + 7 files changed, 137 insertions(+), 71 deletions(-) diff --git a/package.json b/package.json index 7c9990d..df5ebf6 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ }, "dependencies": { "@clack/prompts": "0.7.0", - "@winches/prompts": "0.0.6", + "@winches/prompts": "0.0.7", "async-retry": "1.3.3", "chalk": "5.3.0", "commander": "11.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 12d0161..270c5f8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,8 +12,8 @@ importers: specifier: 0.7.0 version: 0.7.0 '@winches/prompts': - specifier: 0.0.6 - version: 0.0.6 + specifier: 0.0.7 + version: 0.0.7 async-retry: specifier: 1.3.3 version: 1.3.3 @@ -665,8 +665,8 @@ packages: resolution: {integrity: sha512-uVw9VIMFBUTz8rIeaUT3fFe8xIUx8r4ywAdlQv1ifH+6acn/XF8Y6rwJ7XNmkNMDrTW+7+vxFFPIF40nJCVsMQ==} engines: {node: ^16.0.0 || >=18.0.0} - '@winches/prompts@0.0.6': - resolution: {integrity: sha512-8fdmmbad8L2ldIaRSkoCTBeDxmc20CDcmA1d1ut2xFKZoHZlV/VTSffuDChQbHzFhdeYFefjDZn3MJ+06RtYQg==} + '@winches/prompts@0.0.7': + resolution: {integrity: sha512-H/UlFlm83C6zkYn3CK4GF2VMpAlyjO3o623yamOyHwSaehhnj7oAJmklvr73UVMqu6Q+rl4Bzs3PBmxGB8cJVg==} engines: {node: '>= 14'} JSONStream@1.3.5: @@ -3327,7 +3327,7 @@ snapshots: '@typescript-eslint/types': 6.7.2 eslint-visitor-keys: 3.4.3 - '@winches/prompts@0.0.6': + '@winches/prompts@0.0.7': dependencies: kleur: 4.1.5 sisteransi: 1.0.5 diff --git a/src/actions/upgrade-action.ts b/src/actions/upgrade-action.ts index ba68e19..f81c9ff 100644 --- a/src/actions/upgrade-action.ts +++ b/src/actions/upgrade-action.ts @@ -3,6 +3,7 @@ import type {AppendKeyValue} from '@helpers/type'; import fs from 'node:fs'; import {getBetaVersion} from '@helpers/beta'; +import {getCanaryVersion} from '@helpers/canary'; import {checkIllegalComponents} from '@helpers/check'; import {detect} from '@helpers/detect'; import {exec} from '@helpers/exec'; @@ -27,24 +28,35 @@ interface UpgradeActionOptions { patch?: boolean; write?: boolean; beta?: boolean; + canary?: boolean; } type TransformComponent = Required< AppendKeyValue & {isLatest: boolean} >; -function betaCompareVersions(version: string, latestVersion: string, beta: boolean) { +function extraCompareVersions( + version: string, + latestVersion: string, + beta: boolean, + canary: boolean +) { const compareResult = compareVersions(version, latestVersion); // Beta version is greater than latest version if beta is true // Example: 2.1.0 < 2.1.0-beta.0 - return beta && compareResult === 1 && !version.includes('beta') ? false : compareResult >= 0; + return beta && compareResult === 1 && !version.includes('beta') + ? false + : canary && compareResult === 1 && !version.includes('canary') + ? false + : compareResult >= 0; } export async function upgradeAction(components: string[], options: UpgradeActionOptions) { const { all = false, beta = false, + canary = false, packagePath = resolver('package.json'), write = false } = options; @@ -60,8 +72,12 @@ export async function upgradeAction(components: string[], options: UpgradeAction const latestVersion = store.nextUIComponentsMap[component.name]?.version || (await getLatestVersion(component.package)); - const mergedVersion = beta ? await getBetaVersion(component.package) : latestVersion; - const compareResult = betaCompareVersions(component.version, mergedVersion, beta); + const mergedVersion = beta + ? await getBetaVersion(component.package) + : canary + ? await getCanaryVersion(component.package) + : latestVersion; + const compareResult = extraCompareVersions(component.version, mergedVersion, beta, canary); transformComponents.push({ ...component, @@ -103,7 +119,12 @@ export async function upgradeAction(components: string[], options: UpgradeAction components = await getAutocompleteMultiselect( 'Select the components to upgrade', transformComponents.map((component) => { - const isUpToDate = betaCompareVersions(component.version, component.latestVersion, beta); + const isUpToDate = extraCompareVersions( + component.version, + component.latestVersion, + beta, + canary + ); return { disabled: isUpToDate, diff --git a/src/constants/components.json b/src/constants/components.json index 704edc4..a3edae1 100644 --- a/src/constants/components.json +++ b/src/constants/components.json @@ -3,7 +3,7 @@ { "name": "accordion", "package": "@nextui-org/accordion", - "version": "2.1.0-beta.3", + "version": "2.1.0-beta.13", "docs": "https://nextui.org/docs/components/accordion", "description": "Collapse display a list of high-level options that can expand/collapse to reveal more information.", "status": "stable", @@ -11,7 +11,7 @@ "peerDependencies": { "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", - "framer-motion": ">=11.5.6", + "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1", "@nextui-org/theme": ">=2.3.0-beta.0", "@nextui-org/system": ">=2.3.0-beta.0", "tailwindcss": ">=3.4.0" @@ -20,10 +20,10 @@ { "name": "alert", "package": "@nextui-org/alert", - "version": "2.1.0-beta.3", + "version": "2.1.0-beta.14", "docs": "https://nextui.org/docs/components/alert", "description": "Alerts are temporary notifications that provide concise feedback about an action or event.", - "status": "stable", + "status": "new", "style": "", "peerDependencies": { "react": ">=18 || >=19.0.0-rc.0", @@ -36,10 +36,10 @@ { "name": "autocomplete", "package": "@nextui-org/autocomplete", - "version": "2.2.0-beta.5", + "version": "2.2.0-beta.17", "docs": "https://nextui.org/docs/components/autocomplete", "description": "An autocomplete combines a text input with a listbox, allowing users to filter a list of options to items matching a query.", - "status": "stable", + "status": "updated", "style": "", "peerDependencies": { "@nextui-org/system": ">=2.3.0-beta.0", @@ -53,7 +53,7 @@ { "name": "avatar", "package": "@nextui-org/avatar", - "version": "2.1.0-beta.6", + "version": "2.1.0-beta.12", "docs": "https://nextui.org/docs/components/avatar", "description": "The Avatar component is used to represent a user, and displays the profile picture, initials or fallback icon.", "status": "stable", @@ -69,10 +69,10 @@ { "name": "badge", "package": "@nextui-org/badge", - "version": "2.1.0-beta.3", + "version": "2.1.0-beta.8", "docs": "https://nextui.org/docs/components/badge", "description": "Badges are used as a small numerical value or status descriptor for UI elements.", - "status": "updated", + "status": "stable", "style": "", "peerDependencies": { "react": ">=18 || >=19.0.0-rc.0", @@ -85,7 +85,7 @@ { "name": "breadcrumbs", "package": "@nextui-org/breadcrumbs", - "version": "2.1.0-beta.3", + "version": "2.1.0-beta.11", "docs": "https://nextui.org/docs/components/breadcrumbs", "description": "Breadcrumbs display a hierarchy of links to the current page or resource in an application.", "status": "stable", @@ -101,10 +101,10 @@ { "name": "button", "package": "@nextui-org/button", - "version": "2.1.0-beta.3", + "version": "2.1.0-beta.10", "docs": "https://nextui.org/docs/components/button", "description": "Buttons allow users to perform actions and choose with a single tap.", - "status": "stable", + "status": "updated", "style": "", "peerDependencies": { "react": ">=18 || >=19.0.0-rc.0", @@ -118,14 +118,15 @@ { "name": "calendar", "package": "@nextui-org/calendar", - "version": "2.1.0-beta.3", + "version": "2.1.0-beta.14", "docs": "https://nextui.org/docs/components/calendar", "description": "A calendar displays one or more date grids and allows users to select a single date.", - "status": "new", + "status": "stable", "style": "", "peerDependencies": { "@nextui-org/system": ">=2.3.0-beta.0", "@nextui-org/theme": ">=2.3.0-beta.0", + "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1", "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", "tailwindcss": ">=3.4.0" @@ -134,7 +135,7 @@ { "name": "card", "package": "@nextui-org/card", - "version": "2.1.0-beta.3", + "version": "2.1.0-beta.10", "docs": "https://nextui.org/docs/components/card", "description": "Card is a container for text, photos, and actions in the context of a single subject.", "status": "stable", @@ -151,7 +152,7 @@ { "name": "checkbox", "package": "@nextui-org/checkbox", - "version": "2.2.0-beta.3", + "version": "2.2.0-beta.9", "docs": "https://nextui.org/docs/components/checkbox", "description": "Checkboxes allow users to select multiple items from a list of individual items, or to mark one individual item as selected.", "status": "updated", @@ -167,7 +168,7 @@ { "name": "chip", "package": "@nextui-org/chip", - "version": "2.1.0-beta.3", + "version": "2.1.0-beta.11", "docs": "https://nextui.org/docs/components/chip", "description": "Chips help people enter information, make selections, filter content, or trigger actions.", "status": "stable", @@ -183,7 +184,7 @@ { "name": "code", "package": "@nextui-org/code", - "version": "2.1.0-beta.3", + "version": "2.1.0-beta.9", "docs": "https://nextui.org/docs/components/code", "description": "Code is a component used to display inline code.", "status": "stable", @@ -198,10 +199,10 @@ { "name": "date-input", "package": "@nextui-org/date-input", - "version": "2.2.0-beta.3", + "version": "2.2.0-beta.9", "docs": "https://nextui.org/docs/components/date-input", "description": "A date input allows users to enter and edit date and time values using a keyboard.", - "status": "new", + "status": "stable", "style": "", "peerDependencies": { "@nextui-org/system": ">=2.3.0-beta.0", @@ -214,14 +215,15 @@ { "name": "date-picker", "package": "@nextui-org/date-picker", - "version": "2.2.0-beta.4", + "version": "2.2.0-beta.15", "docs": "https://nextui.org/docs/components/date-picker", "description": "A date picker combines a DateInput and a Calendar popover to allow users to enter or select a date and time value.", - "status": "new", + "status": "stable", "style": "", "peerDependencies": { "@nextui-org/system": ">=2.3.0-beta.0", "@nextui-org/theme": ">=2.3.0-beta.0", + "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1", "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", "tailwindcss": ">=3.4.0" @@ -230,7 +232,7 @@ { "name": "divider", "package": "@nextui-org/divider", - "version": "2.1.0-beta.3", + "version": "2.1.0-beta.9", "docs": "https://nextui.org/docs/components/divider", "description": ". A separator is a visual divider between two groups of content", "status": "stable", @@ -245,7 +247,7 @@ { "name": "drawer", "package": "@nextui-org/drawer", - "version": "2.1.0-beta.3", + "version": "2.1.0-beta.14", "docs": "https://nextui.org/docs/components/drawer", "description": "Used to render a content that slides in from the side of the screen.", "status": "new", @@ -261,7 +263,7 @@ { "name": "dropdown", "package": "@nextui-org/dropdown", - "version": "2.2.0-beta.4", + "version": "2.2.0-beta.14", "docs": "https://nextui.org/docs/components/dropdown", "description": "A dropdown displays a list of actions or options that a user can choose.", "status": "stable", @@ -275,10 +277,26 @@ "tailwindcss": ">=3.4.0" } }, + { + "name": "form", + "package": "@nextui-org/form", + "version": "2.0.1-beta.1", + "docs": "https://nextui.org/docs/components/form", + "description": "A form is a group of inputs that allows users submit data to a server and supports field validation errors.", + "status": "stable", + "style": "", + "peerDependencies": { + "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.3.0-beta.0", + "react": ">=18", + "react-dom": ">=18", + "tailwindcss": ">=3.4.0" + } + }, { "name": "image", "package": "@nextui-org/image", - "version": "2.1.0-beta.6", + "version": "2.1.0-beta.11", "docs": "https://nextui.org/docs/components/image", "description": "A simple image component", "status": "stable", @@ -294,10 +312,10 @@ { "name": "input", "package": "@nextui-org/input", - "version": "2.3.0-beta.4", + "version": "2.3.0-beta.12", "docs": "https://nextui.org/docs/components/input", "description": "The input component is designed for capturing user input within a text field.", - "status": "stable", + "status": "updated", "style": "", "peerDependencies": { "react": ">=18 || >=19.0.0-rc.0", @@ -307,10 +325,26 @@ "tailwindcss": ">=3.4.0" } }, + { + "name": "input-otp", + "package": "@nextui-org/input-otp", + "version": "2.0.1-beta.0", + "docs": "https://nextui.org/docs/components/input-otp", + "description": "", + "status": "new", + "style": "", + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18", + "@nextui-org/theme": ">=2.3.0-beta.17", + "@nextui-org/system": ">=2.0.0", + "tailwindcss": ">=3.4.0" + } + }, { "name": "kbd", "package": "@nextui-org/kbd", - "version": "2.1.0-beta.3", + "version": "2.1.0-beta.9", "docs": "https://nextui.org/docs/components/kbd", "description": "The keyboard key components indicates which key or set of keys used to execute a specificv action", "status": "stable", @@ -325,7 +359,7 @@ { "name": "link", "package": "@nextui-org/link", - "version": "2.1.0-beta.3", + "version": "2.1.0-beta.11", "docs": "https://nextui.org/docs/components/link", "description": "Links allow users to click their way from page to page. This component is styled to resemble a hyperlink and semantically renders an <a>", "status": "stable", @@ -341,7 +375,7 @@ { "name": "listbox", "package": "@nextui-org/listbox", - "version": "2.2.0-beta.3", + "version": "2.2.0-beta.14", "docs": "https://nextui.org/docs/components/listbox", "description": "A listbox displays a list of options and allows a user to select one or more of them.", "status": "stable", @@ -357,7 +391,7 @@ { "name": "menu", "package": "@nextui-org/menu", - "version": "2.1.0-beta.3", + "version": "2.1.0-beta.13", "docs": "https://nextui.org/docs/components/menu", "description": "A menu displays a list of options and allows a user to select one or more of them.", "status": "stable", @@ -373,7 +407,7 @@ { "name": "modal", "package": "@nextui-org/modal", - "version": "2.1.0-beta.3", + "version": "2.1.0-beta.14", "docs": "https://nextui.org/docs/components/modal", "description": "Displays a dialog with a custom content that requires attention or provides additional information.", "status": "updated", @@ -390,7 +424,7 @@ { "name": "navbar", "package": "@nextui-org/navbar", - "version": "2.1.0-beta.3", + "version": "2.1.0-beta.11", "docs": "https://nextui.org/docs/components/navbar", "description": "A responsive navigation header positioned on top side of your page that includes support for branding, links, navigation, collapse and more.", "status": "stable", @@ -407,7 +441,7 @@ { "name": "pagination", "package": "@nextui-org/pagination", - "version": "2.1.0-beta.3", + "version": "2.1.0-beta.11", "docs": "https://nextui.org/docs/components/pagination", "description": "The Pagination component allows you to display active page and navigate between multiple pages.", "status": "stable", @@ -423,7 +457,7 @@ { "name": "popover", "package": "@nextui-org/popover", - "version": "2.2.0-beta.4", + "version": "2.2.0-beta.12", "docs": "https://nextui.org/docs/components/popover", "description": "A popover is an overlay element positioned relative to a trigger.", "status": "stable", @@ -440,7 +474,7 @@ { "name": "progress", "package": "@nextui-org/progress", - "version": "2.1.0-beta.3", + "version": "2.1.0-beta.9", "docs": "https://nextui.org/docs/components/progress", "description": "Progress bars show either determinate or indeterminate progress of an operation over time.", "status": "stable", @@ -456,7 +490,7 @@ { "name": "radio", "package": "@nextui-org/radio", - "version": "2.2.0-beta.3", + "version": "2.2.0-beta.9", "docs": "https://nextui.org/docs/components/radio", "description": "Radios allow users to select a single option from a list of mutually exclusive options.", "status": "stable", @@ -472,7 +506,7 @@ { "name": "ripple", "package": "@nextui-org/ripple", - "version": "2.1.0-beta.3", + "version": "2.1.0-beta.8", "docs": "https://nextui.org/docs/components/ripple", "description": "A simple implementation to display a ripple animation when the source component is clicked", "status": "stable", @@ -489,7 +523,7 @@ { "name": "scroll-shadow", "package": "@nextui-org/scroll-shadow", - "version": "2.2.0-beta.3", + "version": "2.2.0-beta.8", "docs": "https://nextui.org/docs/components/scroll-shadow", "description": "A component that applies top and bottom shadows when content overflows on scroll.", "status": "stable", @@ -505,10 +539,10 @@ { "name": "select", "package": "@nextui-org/select", - "version": "2.3.0-beta.5", + "version": "2.3.0-beta.19", "docs": "https://nextui.org/docs/components/select", "description": "A select displays a collapsible list of options and allows a user to select one of them.", - "status": "stable", + "status": "updated", "style": "", "peerDependencies": { "@nextui-org/system": ">=2.3.0-beta.0", @@ -522,10 +556,10 @@ { "name": "skeleton", "package": "@nextui-org/skeleton", - "version": "2.1.0-beta.3", + "version": "2.1.0-beta.8", "docs": "https://nextui.org/docs/components/skeleton", "description": "Skeleton is used to display the loading state of some component.", - "status": "updated", + "status": "stable", "style": "", "peerDependencies": { "react": ">=18 || >=19.0.0-rc.0", @@ -538,7 +572,7 @@ { "name": "slider", "package": "@nextui-org/slider", - "version": "2.3.0-beta.3", + "version": "2.3.0-beta.11", "docs": "https://nextui.org/docs/components/slider", "description": "A slider allows a user to select one or more values within a range.", "status": "stable", @@ -554,7 +588,7 @@ { "name": "snippet", "package": "@nextui-org/snippet", - "version": "2.1.0-beta.3", + "version": "2.1.0-beta.13", "docs": "https://nextui.org/docs/components/snippet", "description": "Display a snippet of copyable code for the command line.", "status": "stable", @@ -571,7 +605,7 @@ { "name": "spacer", "package": "@nextui-org/spacer", - "version": "2.1.0-beta.3", + "version": "2.1.0-beta.9", "docs": "https://nextui.org/docs/components/spacer", "description": "A flexible spacer component designed to create consistent spacing and maintain alignment in your layout.", "status": "stable", @@ -586,7 +620,7 @@ { "name": "spinner", "package": "@nextui-org/spinner", - "version": "2.1.0-beta.3", + "version": "2.1.0-beta.9", "docs": "https://nextui.org/docs/components/spinner", "description": "Loaders express an unspecified wait time or display the length of a process.", "status": "stable", @@ -601,10 +635,10 @@ { "name": "switch", "package": "@nextui-org/switch", - "version": "2.1.0-beta.3", + "version": "2.1.0-beta.9", "docs": "https://nextui.org/docs/components/switch", "description": "A switch is similar to a checkbox, but represents on/off values as opposed to selection.", - "status": "stable", + "status": "updated", "style": "toggle", "peerDependencies": { "react": ">=18 || >=19.0.0-rc.0", @@ -617,7 +651,7 @@ { "name": "table", "package": "@nextui-org/table", - "version": "2.1.0-beta.3", + "version": "2.1.0-beta.12", "docs": "https://nextui.org/docs/components/table", "description": "Tables are used to display tabular data using rows and columns. ", "status": "stable", @@ -633,10 +667,10 @@ { "name": "tabs", "package": "@nextui-org/tabs", - "version": "2.1.0-beta.3", + "version": "2.1.0-beta.11", "docs": "https://nextui.org/docs/components/tabs", "description": "Tabs organize content into multiple sections and allow users to navigate between them.", - "status": "updated", + "status": "stable", "style": "", "peerDependencies": { "react": ">=18 || >=19.0.0-rc.0", @@ -650,10 +684,10 @@ { "name": "tooltip", "package": "@nextui-org/tooltip", - "version": "2.1.0-beta.3", + "version": "2.1.0-beta.11", "docs": "https://nextui.org/docs/components/tooltip", "description": "A React Component for rendering dynamically positioned Tooltips", - "status": "updated", + "status": "stable", "style": "popover", "peerDependencies": { "react": ">=18 || >=19.0.0-rc.0", @@ -667,7 +701,7 @@ { "name": "user", "package": "@nextui-org/user", - "version": "2.1.0-beta.6", + "version": "2.1.0-beta.12", "docs": "https://nextui.org/docs/components/user", "description": "Flexible User Profile Component.", "status": "stable", @@ -681,7 +715,7 @@ } } ], - "betaVersion": "2.5.0-beta.8", + "betaVersion": "2.5.0-beta.26", "components": [ { "name": "accordion", @@ -2113,5 +2147,5 @@ } } ], - "canaryVersion": "0.0.0-canary-20241204130109" + "canaryVersion": "0.0.0-canary-20241205120225" } diff --git a/src/constants/store.ts b/src/constants/store.ts index 9aa3f7d..32a5830 100644 --- a/src/constants/store.ts +++ b/src/constants/store.ts @@ -20,6 +20,8 @@ export type Store = { nextUIComponentsKeysSet: Set; nextUIComponentsMap: NextUIComponentsMap; nextUIComponentsPackageMap: NextUIComponentsMap; + beta: boolean; + canary: boolean; }; export const store = {} as Store; diff --git a/src/helpers/upgrade.ts b/src/helpers/upgrade.ts index 4ecbd4e..4c2594b 100644 --- a/src/helpers/upgrade.ts +++ b/src/helpers/upgrade.ts @@ -3,10 +3,12 @@ import type {RequiredKey, SAFE_ANY} from './type'; import chalk from 'chalk'; import {NEXT_UI, THEME_UI} from 'src/constants/required'; -import {store} from 'src/constants/store'; +import {getStoreSync, store} from 'src/constants/store'; import {getCacheExecData} from 'src/scripts/cache/cache'; import {type Dependencies, compareVersions, getLatestVersion} from 'src/scripts/helpers'; +import {getBetaVersion} from './beta'; +import {getCanaryVersion} from './canary'; import {Logger} from './logger'; import {colorMatchRegex, outputBox} from './output-info'; import { @@ -197,7 +199,11 @@ export async function getPackagePeerDep( } const {versionMode} = getVersionAndMode(allDependencies, peerPackage); - let formatPeerVersion = transformPeerVersion(peerVersion); + let formatPeerVersion = getStoreSync('beta') + ? await getBetaVersion(peerPackage) + : getStoreSync('canary') + ? await getCanaryVersion(peerPackage) + : transformPeerVersion(peerVersion); const isLatest = compareVersions(currentVersion, formatPeerVersion) >= 0; if (isLatest) { diff --git a/src/index.ts b/src/index.ts index c5ff9ac..7e617ec 100644 --- a/src/index.ts +++ b/src/index.ts @@ -111,6 +111,7 @@ nextui .option('-a --all [boolean]', 'Upgrade all components', false) .option('-w --write [boolean]', 'Write the upgrade version to package.json file', false) .option('-b --beta [boolean]', 'Upgrade beta components', false) + .option('-c --canary [boolean]', 'Upgrade canary components', false) .action(upgradeAction); nextui @@ -158,6 +159,8 @@ nextui.hook('preAction', async (command) => { initCache(noCache); // Init debug store.debug = debug; + store.beta = beta; + store.canary = canary; if (args && commandList.includes(args as CommandName)) { // Before run the command init the components.json From 9234f72ca1743df2551fc644fd57ab01e566d6db Mon Sep 17 00:00:00 2001 From: winches <329487092@qq.com> Date: Thu, 5 Dec 2024 23:36:28 +0800 Subject: [PATCH 04/10] fix: upgrade --all version --- src/actions/upgrade-action.ts | 12 +++++++----- src/helpers/check.ts | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/actions/upgrade-action.ts b/src/actions/upgrade-action.ts index f81c9ff..baf207d 100644 --- a/src/actions/upgrade-action.ts +++ b/src/actions/upgrade-action.ts @@ -4,7 +4,7 @@ import fs from 'node:fs'; import {getBetaVersion} from '@helpers/beta'; import {getCanaryVersion} from '@helpers/canary'; -import {checkIllegalComponents} from '@helpers/check'; +import {checkIllegalComponents, getConditionData} from '@helpers/check'; import {detect} from '@helpers/detect'; import {exec} from '@helpers/exec'; import {Logger} from '@helpers/logger'; @@ -99,12 +99,14 @@ export async function upgradeAction(components: string[], options: UpgradeAction } else if (!components.length) { // If have the main nextui then add if (isNextUIAll) { + const version = transformPeerVersion(allDependencies[NEXT_UI]); + const conditionData = getConditionData(store.beta, store.canary); + const latestVersion = conditionData?.version ?? store.latestVersion; const nextuiData = { - isLatest: - compareVersions(store.latestVersion, transformPeerVersion(allDependencies[NEXT_UI])) <= 0, - latestVersion: store.latestVersion, + isLatest: extraCompareVersions(latestVersion, version, store.beta, store.canary), + latestVersion, package: NEXT_UI, - version: transformPeerVersion(allDependencies[NEXT_UI]) + version } as TransformComponent; transformComponents.push(nextuiData); diff --git a/src/helpers/check.ts b/src/helpers/check.ts index e2a35ba..5f744fb 100644 --- a/src/helpers/check.ts +++ b/src/helpers/check.ts @@ -110,7 +110,7 @@ interface CheckPeerDependenciesConfig { canary?: boolean; } -function getConditionData(beta: boolean, canary: boolean) { +export function getConditionData(beta: boolean, canary: boolean) { return beta ? {tag: 'beta', version: store.betaVersion} : canary From f41230a8ddf484bacca1e68e21ef8eac1de67a15 Mon Sep 17 00:00:00 2001 From: winches <329487092@qq.com> Date: Fri, 6 Dec 2024 00:03:51 +0800 Subject: [PATCH 05/10] fix: upgrade command version --- src/actions/upgrade-action.ts | 8 ++++---- src/helpers/check.ts | 4 ++++ src/helpers/upgrade.ts | 3 ++- src/scripts/helpers.ts | 8 +++++--- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/actions/upgrade-action.ts b/src/actions/upgrade-action.ts index baf207d..19d882a 100644 --- a/src/actions/upgrade-action.ts +++ b/src/actions/upgrade-action.ts @@ -4,7 +4,7 @@ import fs from 'node:fs'; import {getBetaVersion} from '@helpers/beta'; import {getCanaryVersion} from '@helpers/canary'; -import {checkIllegalComponents, getConditionData} from '@helpers/check'; +import {checkIllegalComponents, getConditionLatestVersion} from '@helpers/check'; import {detect} from '@helpers/detect'; import {exec} from '@helpers/exec'; import {Logger} from '@helpers/logger'; @@ -44,6 +44,7 @@ function extraCompareVersions( const compareResult = compareVersions(version, latestVersion); // Beta version is greater than latest version if beta is true + // compareResult(2.1.0, 2.1.0-beta.0) = 1 // Example: 2.1.0 < 2.1.0-beta.0 return beta && compareResult === 1 && !version.includes('beta') ? false @@ -100,10 +101,9 @@ export async function upgradeAction(components: string[], options: UpgradeAction // If have the main nextui then add if (isNextUIAll) { const version = transformPeerVersion(allDependencies[NEXT_UI]); - const conditionData = getConditionData(store.beta, store.canary); - const latestVersion = conditionData?.version ?? store.latestVersion; + const latestVersion = getConditionLatestVersion(store.beta, store.canary); const nextuiData = { - isLatest: extraCompareVersions(latestVersion, version, store.beta, store.canary), + isLatest: extraCompareVersions(version, latestVersion, store.beta, store.canary), latestVersion, package: NEXT_UI, version diff --git a/src/helpers/check.ts b/src/helpers/check.ts index 5f744fb..1a69c83 100644 --- a/src/helpers/check.ts +++ b/src/helpers/check.ts @@ -118,6 +118,10 @@ export function getConditionData(beta: boolean, canary: boolean) { : null; } +export function getConditionLatestVersion(beta: boolean, canary: boolean) { + return beta ? store.betaVersion : canary ? store.canaryVersion : store.latestVersion; +} + /** * Check if the required content is installed * @example return result and missing required [false, '@nextui-org/react', 'framer-motion'] diff --git a/src/helpers/upgrade.ts b/src/helpers/upgrade.ts index 4c2594b..0b7b17f 100644 --- a/src/helpers/upgrade.ts +++ b/src/helpers/upgrade.ts @@ -9,6 +9,7 @@ import {type Dependencies, compareVersions, getLatestVersion} from 'src/scripts/ import {getBetaVersion} from './beta'; import {getCanaryVersion} from './canary'; +import {getConditionLatestVersion} from './check'; import {Logger} from './logger'; import {colorMatchRegex, outputBox} from './output-info'; import { @@ -269,7 +270,7 @@ export async function getAllOutputData( }; } - const latestVersion = store.latestVersion; + const latestVersion = getConditionLatestVersion(store.beta, store.canary); const {currentVersion, versionMode} = getVersionAndMode(allDependencies, NEXT_UI); const colorVersion = getColorVersion(currentVersion, latestVersion); diff --git a/src/scripts/helpers.ts b/src/scripts/helpers.ts index 7e4f41e..d94e55c 100644 --- a/src/scripts/helpers.ts +++ b/src/scripts/helpers.ts @@ -72,9 +72,11 @@ export async function updateComponents(options?: UpdateComponentsOptions) { const currentVersion = components.version; const betaVersion = components.betaVersion; const canaryVersion = components.canaryVersion; - const latestVersion = await getStore('latestVersion'); - const latestBetaVersion = await getStore('betaVersion'); - const latestCanaryVersion = await getStore('canaryVersion'); + const [latestVersion, latestBetaVersion, latestCanaryVersion] = await Promise.all([ + getStore('latestVersion'), + getStore('betaVersion'), + getStore('canaryVersion') + ]); if ( compareVersions(currentVersion, latestVersion) === -1 || From 01a10a07578c02779cb1f20af3ac8a372db86e83 Mon Sep 17 00:00:00 2001 From: winches <329487092@qq.com> Date: Mon, 9 Dec 2024 21:35:47 +0800 Subject: [PATCH 06/10] fix: init data if dont exist components path --- src/scripts/helpers.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/scripts/helpers.ts b/src/scripts/helpers.ts index ea65ff0..0f2eafb 100644 --- a/src/scripts/helpers.ts +++ b/src/scripts/helpers.ts @@ -170,9 +170,11 @@ export async function autoUpdateComponents( ) { let {betaVersion, canaryVersion, latestVersion} = options; const {beta, canary} = options; + const existComponentsPath = existsSync(COMPONENTS_PATH); [latestVersion, betaVersion, canaryVersion] = await Promise.all([ - !beta && !canary && (latestVersion || getStore('latestVersion')), + // If the components.json is not exist, then we need to download the latest version + ((!beta && !canary) || !existComponentsPath) && (latestVersion || getStore('latestVersion')), beta && (betaVersion || getStore('betaVersion')), canary && (canaryVersion || getStore('canaryVersion')) ] as string[]); @@ -183,8 +185,8 @@ export async function autoUpdateComponents( canaryVersion ? downloadFile(getUnpkgUrl(canaryVersion)) : Promise.resolve([]) ]); - const originalComponentsJson = JSON.parse( - readFileSync(COMPONENTS_PATH, 'utf-8') + const originalComponentsJson = ( + existComponentsPath ? JSON.parse(readFileSync(COMPONENTS_PATH, 'utf-8')) : {components} ) as ComponentsJson; const filterMissingComponents = beta From 36a1dc7865fa0f22f625a485869cad7a387c8541 Mon Sep 17 00:00:00 2001 From: winches <329487092@qq.com> Date: Mon, 9 Dec 2024 22:56:10 +0800 Subject: [PATCH 07/10] feat: adapt canary components and some optimizations --- src/constants/component.ts | 13 ++++++-- src/constants/store.ts | 17 +++++++++- src/helpers/canary.ts | 10 ++++-- src/helpers/upgrade.ts | 1 + src/index.ts | 10 ++++-- src/scripts/helpers.ts | 42 ++++++++++++++++++------- src/scripts/update/update-components.ts | 2 ++ 7 files changed, 76 insertions(+), 19 deletions(-) diff --git a/src/constants/component.ts b/src/constants/component.ts index 89c06b7..6594cab 100644 --- a/src/constants/component.ts +++ b/src/constants/component.ts @@ -29,10 +29,12 @@ export function getNextuiComponentsData(nextUIComponents: Components) { } export function initStoreComponentsData({ - beta, + beta = false, + canary = false, nextUIComponents }: { - beta: boolean; + beta?: boolean; + canary?: boolean; nextUIComponents: Components; }) { const { @@ -50,6 +52,13 @@ export function initStoreComponentsData({ store.betaNextUIComponentsMap = nextUIComponentsMap; store.betaNextUIComponentsPackageMap = nextUIComponentsPackageMap; store.betaNextUIcomponentsPackages = nextUIcomponentsPackages; + } else if (canary) { + store.canaryNextUIComponents = nextUIComponents; + store.canaryNextUIComponentsKeys = nextUIComponentsKeys; + store.canaryNextUIComponentsKeysSet = nextUIComponentsKeysSet; + store.canaryNextUIComponentsMap = nextUIComponentsMap; + store.canaryNextUIComponentsPackageMap = nextUIComponentsPackageMap; + store.canaryNextUIcomponentsPackages = nextUIcomponentsPackages; } else { store.nextUIComponents = nextUIComponents; store.nextUIComponentsKeys = nextUIComponentsKeys; diff --git a/src/constants/store.ts b/src/constants/store.ts index f2cbdda..c6a0f0b 100644 --- a/src/constants/store.ts +++ b/src/constants/store.ts @@ -33,6 +33,14 @@ export type Store = { betaNextUIComponentsKeysSet: Set; betaNextUIComponentsMap: NextUIComponentsMap; betaNextUIComponentsPackageMap: NextUIComponentsMap; + + // Canary NextUI + canaryNextUIComponents: Components; + canaryNextUIComponentsKeys: string[]; + canaryNextUIcomponentsPackages: string[]; + canaryNextUIComponentsKeysSet: Set; + canaryNextUIComponentsMap: NextUIComponentsMap; + canaryNextUIComponentsPackageMap: NextUIComponentsMap; }; /* eslint-disable sort-keys-fix/sort-keys-fix, sort-keys */ @@ -58,7 +66,14 @@ export const store = { nextUIComponentsKeysSet: new Set(), nextUIComponentsMap: {}, nextUIComponentsPackageMap: {}, - nextUIcomponentsPackages: [] + nextUIcomponentsPackages: [], + + canaryNextUIComponents: [], + canaryNextUIComponentsKeys: [], + canaryNextUIcomponentsPackages: [], + canaryNextUIComponentsKeysSet: new Set(), + canaryNextUIComponentsMap: {}, + canaryNextUIComponentsPackageMap: {} } as Store; /* eslint-enable sort-keys-fix/sort-keys-fix, sort-keys */ diff --git a/src/helpers/canary.ts b/src/helpers/canary.ts index 1cb5070..860f149 100644 --- a/src/helpers/canary.ts +++ b/src/helpers/canary.ts @@ -1,8 +1,14 @@ +import {store} from 'src/constants/store'; + import {getPackageVersionData, getPrefixComponent} from './beta'; import {Logger} from './logger'; -export async function getCanaryVersion(component: string) { - const data = await getPackageVersionData(component); +export async function getCanaryVersion(componentName: string) { + if (store.canaryNextUIComponentsPackageMap[componentName]) { + return store.canaryNextUIComponentsPackageMap[componentName]!.version; + } + + const data = await getPackageVersionData(componentName); try { return JSON.parse(data).canary; diff --git a/src/helpers/upgrade.ts b/src/helpers/upgrade.ts index 1014eee..3a7f5c2 100644 --- a/src/helpers/upgrade.ts +++ b/src/helpers/upgrade.ts @@ -205,6 +205,7 @@ export async function getPackagePeerDep( : transformPeerVersion(peerVersion); if (!currentVersion) { + // If the peer package is not installed, then add minimum version to the missingDepList missingDepList.add({name: peerPackage, version: formatPeerVersion}); continue; } diff --git a/src/index.ts b/src/index.ts index 823ed4c..f5e7007 100644 --- a/src/index.ts +++ b/src/index.ts @@ -164,11 +164,15 @@ nextui.hook('preAction', async (command) => { if (args && commandList.includes(args as CommandName)) { // Before run the command init the components.json - const nextUIComponents = (await getComponents()).components; - const nextUIComponentsBeta = (await getComponents()).betaComponents; + const components = await getComponents(); + const nextUIComponents = components.components; + const nextUIComponentsBeta = components.betaComponents; + const nextUIComponentsCanary = components.canaryComponents; - initStoreComponentsData({beta: false, nextUIComponents}); + initStoreComponentsData({nextUIComponents}); store.beta && initStoreComponentsData({beta: true, nextUIComponents: nextUIComponentsBeta}); + store.canary && + initStoreComponentsData({canary: true, nextUIComponents: nextUIComponentsCanary}); } const [cliLatestVersion, latestVersion] = await Promise.all([ diff --git a/src/scripts/helpers.ts b/src/scripts/helpers.ts index 0f2eafb..868c389 100644 --- a/src/scripts/helpers.ts +++ b/src/scripts/helpers.ts @@ -29,11 +29,11 @@ export type Components = { export type ComponentsJson = { version: string; + betaVersion: string; + canaryVersion: string; components: Components; betaComponents: Components; - betaVersion: string; canaryComponents: Components; - canaryVersion: string; }; interface UpdateComponentsOptions { @@ -59,11 +59,11 @@ export function compareVersions(version1 = '', version2 = '') { } export async function updateComponents(options?: UpdateComponentsOptions) { - const {beta = false, canary = false} = options ?? {}; + const {beta = store.beta, canary = store.canary} = options ?? {}; if (!existsSync(COMPONENTS_PATH)) { // First time download the latest date from net - await autoUpdateComponents(); + await autoUpdateComponents({beta, canary}); return; } @@ -166,7 +166,7 @@ export async function autoUpdateComponents( latestVersion?: string; betaVersion?: string; canaryVersion?: string; - } & UpdateComponentsOptions = {beta: true, canary: true} + } & UpdateComponentsOptions ) { let {betaVersion, canaryVersion, latestVersion} = options; const {beta, canary} = options; @@ -180,9 +180,19 @@ export async function autoUpdateComponents( ] as string[]); const [components, betaComponents, canaryComponents] = await Promise.all([ - latestVersion ? downloadFile(getUnpkgUrl(latestVersion)) : Promise.resolve([]), - betaVersion ? downloadFile(getUnpkgUrl(betaVersion)) : Promise.resolve([]), - canaryVersion ? downloadFile(getUnpkgUrl(canaryVersion)) : Promise.resolve([]) + latestVersion ? downloadFile({url: getUnpkgUrl(latestVersion)}) : Promise.resolve([]), + betaVersion + ? downloadFile({ + successText: 'Beta components updated successfully!', + url: getUnpkgUrl(betaVersion) + }) + : Promise.resolve([]), + canaryVersion + ? downloadFile({ + successText: 'Canary components updated successfully!', + url: getUnpkgUrl(canaryVersion) + }) + : Promise.resolve([]) ]); const originalComponentsJson = ( @@ -199,7 +209,7 @@ export async function autoUpdateComponents( ) : []; - // Add missing beta components to components + // Add missing beta/canary components to components components.push(...(filterMissingComponents ?? [])); const componentsJson: ComponentsJson = { @@ -215,7 +225,15 @@ export async function autoUpdateComponents( return componentsJson; } -export async function downloadFile(url: string, log = true): Promise { +export async function downloadFile({ + log = true, + successText, + url +}: { + url: string; + log?: boolean; + successText?: string; +}): Promise { let data; await oraPromise( @@ -247,7 +265,9 @@ export async function downloadFile(url: string, log = true): Promise log && Logger.prefix('error', `Update components data error: ${error}`); process.exit(1); }, - ...(log ? {successText: chalk.greenBright('Components data updated successfully!\n')} : {}), + ...(log + ? {successText: chalk.greenBright(successText ?? 'Components data updated successfully!\n')} + : {}), text: 'Fetching components data...' } ); diff --git a/src/scripts/update/update-components.ts b/src/scripts/update/update-components.ts index 3ad9bf5..6290068 100644 --- a/src/scripts/update/update-components.ts +++ b/src/scripts/update/update-components.ts @@ -8,5 +8,7 @@ if (!isGithubAction) { initCache(true); // Update beta components store.beta = true; + // Update canary components + store.canary = true; updateComponents(); } From c378def10575d14b8dbf7a19d1f522bc8cce548f Mon Sep 17 00:00:00 2001 From: winches <329487092@qq.com> Date: Tue, 10 Dec 2024 00:05:52 +0800 Subject: [PATCH 08/10] fix: update components script --- src/constants/components.json | 258 ++++++++++++------------ src/scripts/helpers.ts | 11 +- src/scripts/update/update-components.ts | 2 +- 3 files changed, 137 insertions(+), 134 deletions(-) diff --git a/src/constants/components.json b/src/constants/components.json index 0ca9b2e..28ff109 100644 --- a/src/constants/components.json +++ b/src/constants/components.json @@ -1464,12 +1464,12 @@ } } ], - "version": "2.4.8", + "version": "2.6.5", "canaryComponents": [ { "name": "accordion", "package": "@nextui-org/accordion", - "version": "2.1.0", + "version": "2.2.4", "docs": "https://nextui.org/docs/components/accordion", "description": "Collapse display a list of high-level options that can expand/collapse to reveal more information.", "status": "stable", @@ -1478,15 +1478,15 @@ "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1", - "@nextui-org/theme": ">=2.3.0-beta.0", - "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.4.0", + "@nextui-org/system": ">=2.4.0", "tailwindcss": ">=3.4.0" } }, { "name": "alert", "package": "@nextui-org/alert", - "version": "2.1.0", + "version": "2.2.4", "docs": "https://nextui.org/docs/components/alert", "description": "Alerts are temporary notifications that provide concise feedback about an action or event.", "status": "new", @@ -1494,22 +1494,22 @@ "peerDependencies": { "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", - "@nextui-org/theme": ">=2.3.0-beta.0", - "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.4.0", + "@nextui-org/system": ">=2.4.0", "tailwindcss": ">=3.4.0" } }, { "name": "autocomplete", "package": "@nextui-org/autocomplete", - "version": "2.2.0", + "version": "2.3.4", "docs": "https://nextui.org/docs/components/autocomplete", "description": "An autocomplete combines a text input with a listbox, allowing users to filter a list of options to items matching a query.", "status": "updated", "style": "", "peerDependencies": { - "@nextui-org/system": ">=2.3.0-beta.0", - "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.4.0", + "@nextui-org/theme": ">=2.4.0", "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1", "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", @@ -1519,7 +1519,7 @@ { "name": "avatar", "package": "@nextui-org/avatar", - "version": "2.1.0", + "version": "2.2.4", "docs": "https://nextui.org/docs/components/avatar", "description": "The Avatar component is used to represent a user, and displays the profile picture, initials or fallback icon.", "status": "stable", @@ -1527,15 +1527,15 @@ "peerDependencies": { "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", - "@nextui-org/theme": ">=2.3.0-beta.0", - "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.4.0", + "@nextui-org/system": ">=2.4.0", "tailwindcss": ">=3.4.0" } }, { "name": "badge", "package": "@nextui-org/badge", - "version": "2.1.0", + "version": "2.2.3", "docs": "https://nextui.org/docs/components/badge", "description": "Badges are used as a small numerical value or status descriptor for UI elements.", "status": "stable", @@ -1543,15 +1543,15 @@ "peerDependencies": { "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", - "@nextui-org/theme": ">=2.3.0-beta.0", - "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.4.0", + "@nextui-org/system": ">=2.4.0", "tailwindcss": ">=3.4.0" } }, { "name": "breadcrumbs", "package": "@nextui-org/breadcrumbs", - "version": "2.1.0", + "version": "2.2.4", "docs": "https://nextui.org/docs/components/breadcrumbs", "description": "Breadcrumbs display a hierarchy of links to the current page or resource in an application.", "status": "stable", @@ -1559,15 +1559,15 @@ "peerDependencies": { "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", - "@nextui-org/theme": ">=2.3.0-beta.0", - "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.4.0", + "@nextui-org/system": ">=2.4.0", "tailwindcss": ">=3.4.0" } }, { "name": "button", "package": "@nextui-org/button", - "version": "2.1.0", + "version": "2.2.4", "docs": "https://nextui.org/docs/components/button", "description": "Buttons allow users to perform actions and choose with a single tap.", "status": "updated", @@ -1576,22 +1576,22 @@ "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1", - "@nextui-org/theme": ">=2.3.0-beta.0", - "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.4.0", + "@nextui-org/system": ">=2.4.0", "tailwindcss": ">=3.4.0" } }, { "name": "calendar", "package": "@nextui-org/calendar", - "version": "2.1.0", + "version": "2.2.4", "docs": "https://nextui.org/docs/components/calendar", "description": "A calendar displays one or more date grids and allows users to select a single date.", "status": "stable", "style": "", "peerDependencies": { - "@nextui-org/system": ">=2.3.0-beta.0", - "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.4.0", + "@nextui-org/theme": ">=2.4.0", "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1", "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", @@ -1601,7 +1601,7 @@ { "name": "card", "package": "@nextui-org/card", - "version": "2.1.0", + "version": "2.2.4", "docs": "https://nextui.org/docs/components/card", "description": "Card is a container for text, photos, and actions in the context of a single subject.", "status": "stable", @@ -1610,22 +1610,22 @@ "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1", - "@nextui-org/theme": ">=2.3.0-beta.0", - "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.4.0", + "@nextui-org/system": ">=2.4.0", "tailwindcss": ">=3.4.0" } }, { "name": "checkbox", "package": "@nextui-org/checkbox", - "version": "2.2.0", + "version": "2.3.4", "docs": "https://nextui.org/docs/components/checkbox", "description": "Checkboxes allow users to select multiple items from a list of individual items, or to mark one individual item as selected.", "status": "updated", "style": "", "peerDependencies": { - "@nextui-org/system": ">=2.3.0-beta.0", - "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.4.0", + "@nextui-org/theme": ">=2.4.0", "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", "tailwindcss": ">=3.4.0" @@ -1634,7 +1634,7 @@ { "name": "chip", "package": "@nextui-org/chip", - "version": "2.1.0", + "version": "2.2.4", "docs": "https://nextui.org/docs/components/chip", "description": "Chips help people enter information, make selections, filter content, or trigger actions.", "status": "stable", @@ -1642,15 +1642,15 @@ "peerDependencies": { "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", - "@nextui-org/theme": ">=2.3.0-beta.0", - "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.4.0", + "@nextui-org/system": ">=2.4.0", "tailwindcss": ">=3.4.0" } }, { "name": "code", "package": "@nextui-org/code", - "version": "2.1.0", + "version": "2.2.4", "docs": "https://nextui.org/docs/components/code", "description": "Code is a component used to display inline code.", "status": "stable", @@ -1658,21 +1658,21 @@ "peerDependencies": { "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", - "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.4.0", "tailwindcss": ">=3.4.0" } }, { "name": "date-input", "package": "@nextui-org/date-input", - "version": "2.2.0", + "version": "2.3.4", "docs": "https://nextui.org/docs/components/date-input", "description": "A date input allows users to enter and edit date and time values using a keyboard.", "status": "stable", "style": "", "peerDependencies": { - "@nextui-org/system": ">=2.3.0-beta.0", - "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.4.0", + "@nextui-org/theme": ">=2.4.0", "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", "tailwindcss": ">=3.4.0" @@ -1681,14 +1681,14 @@ { "name": "date-picker", "package": "@nextui-org/date-picker", - "version": "2.2.0", + "version": "2.3.4", "docs": "https://nextui.org/docs/components/date-picker", "description": "A date picker combines a DateInput and a Calendar popover to allow users to enter or select a date and time value.", "status": "stable", "style": "", "peerDependencies": { - "@nextui-org/system": ">=2.3.0-beta.0", - "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.4.0", + "@nextui-org/theme": ">=2.4.0", "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1", "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", @@ -1698,7 +1698,7 @@ { "name": "divider", "package": "@nextui-org/divider", - "version": "2.1.0", + "version": "2.2.4", "docs": "https://nextui.org/docs/components/divider", "description": ". A separator is a visual divider between two groups of content", "status": "stable", @@ -1706,14 +1706,14 @@ "peerDependencies": { "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", - "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.4.0", "tailwindcss": ">=3.4.0" } }, { "name": "drawer", "package": "@nextui-org/drawer", - "version": "2.1.0", + "version": "2.2.4", "docs": "https://nextui.org/docs/components/drawer", "description": "Used to render a content that slides in from the side of the screen.", "status": "new", @@ -1721,22 +1721,22 @@ "peerDependencies": { "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", - "@nextui-org/theme": ">=2.3.0-beta.0", - "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.4.0", + "@nextui-org/system": ">=2.4.0", "tailwindcss": ">=3.4.0" } }, { "name": "dropdown", "package": "@nextui-org/dropdown", - "version": "2.2.0", + "version": "2.3.4", "docs": "https://nextui.org/docs/components/dropdown", "description": "A dropdown displays a list of actions or options that a user can choose.", "status": "stable", "style": "", "peerDependencies": { - "@nextui-org/system": ">=2.3.0-beta.0", - "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.4.0", + "@nextui-org/theme": ">=2.4.0", "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1", "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", @@ -1746,14 +1746,14 @@ { "name": "form", "package": "@nextui-org/form", - "version": "2.0.1", + "version": "2.1.4", "docs": "https://nextui.org/docs/components/form", "description": "A form is a group of inputs that allows users submit data to a server and supports field validation errors.", "status": "new", "style": "", "peerDependencies": { - "@nextui-org/system": ">=2.3.0-beta.0", - "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.4.0", + "@nextui-org/theme": ">=2.4.0", "react": ">=18", "react-dom": ">=18", "tailwindcss": ">=3.4.0" @@ -1762,7 +1762,7 @@ { "name": "image", "package": "@nextui-org/image", - "version": "2.1.0", + "version": "2.2.3", "docs": "https://nextui.org/docs/components/image", "description": "A simple image component", "status": "stable", @@ -1770,15 +1770,15 @@ "peerDependencies": { "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", - "@nextui-org/theme": ">=2.3.0-beta.0", - "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.4.0", + "@nextui-org/system": ">=2.4.0", "tailwindcss": ">=3.4.0" } }, { "name": "input", "package": "@nextui-org/input", - "version": "2.3.0", + "version": "2.4.4", "docs": "https://nextui.org/docs/components/input", "description": "The input component is designed for capturing user input within a text field.", "status": "updated", @@ -1786,15 +1786,15 @@ "peerDependencies": { "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", - "@nextui-org/theme": ">=2.3.0-beta.0", - "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.4.0", + "@nextui-org/system": ">=2.4.0", "tailwindcss": ">=3.4.0" } }, { "name": "input-otp", "package": "@nextui-org/input-otp", - "version": "2.0.1", + "version": "2.1.4", "docs": "https://nextui.org/docs/components/input-otp", "description": "", "status": "new", @@ -1802,15 +1802,15 @@ "peerDependencies": { "react": ">=18", "react-dom": ">=18", - "@nextui-org/theme": ">=2.3.0-beta.0", - "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.4.0", + "@nextui-org/system": ">=2.4.0", "tailwindcss": ">=3.4.0" } }, { "name": "kbd", "package": "@nextui-org/kbd", - "version": "2.1.0", + "version": "2.2.4", "docs": "https://nextui.org/docs/components/kbd", "description": "The keyboard key components indicates which key or set of keys used to execute a specificv action", "status": "stable", @@ -1818,14 +1818,14 @@ "peerDependencies": { "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", - "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.4.0", "tailwindcss": ">=3.4.0" } }, { "name": "link", "package": "@nextui-org/link", - "version": "2.1.0", + "version": "2.2.4", "docs": "https://nextui.org/docs/components/link", "description": "Links allow users to click their way from page to page. This component is styled to resemble a hyperlink and semantically renders an <a>", "status": "stable", @@ -1833,15 +1833,15 @@ "peerDependencies": { "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", - "@nextui-org/theme": ">=2.3.0-beta.0", - "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.4.0", + "@nextui-org/system": ">=2.4.0", "tailwindcss": ">=3.4.0" } }, { "name": "listbox", "package": "@nextui-org/listbox", - "version": "2.2.0", + "version": "2.3.4", "docs": "https://nextui.org/docs/components/listbox", "description": "A listbox displays a list of options and allows a user to select one or more of them.", "status": "updated", @@ -1849,15 +1849,15 @@ "peerDependencies": { "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", - "@nextui-org/theme": ">=2.3.0-beta.0", - "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.4.0", + "@nextui-org/system": ">=2.4.0", "tailwindcss": ">=3.4.0" } }, { "name": "menu", "package": "@nextui-org/menu", - "version": "2.1.0", + "version": "2.2.4", "docs": "https://nextui.org/docs/components/menu", "description": "A menu displays a list of options and allows a user to select one or more of them.", "status": "stable", @@ -1865,15 +1865,15 @@ "peerDependencies": { "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", - "@nextui-org/theme": ">=2.3.0-beta.0", - "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.4.0", + "@nextui-org/system": ">=2.4.0", "tailwindcss": ">=3.4.0" } }, { "name": "modal", "package": "@nextui-org/modal", - "version": "2.1.0", + "version": "2.2.4", "docs": "https://nextui.org/docs/components/modal", "description": "Displays a dialog with a custom content that requires attention or provides additional information.", "status": "updated", @@ -1882,15 +1882,15 @@ "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1", - "@nextui-org/theme": ">=2.3.0-beta.0", - "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.4.0", + "@nextui-org/system": ">=2.4.0", "tailwindcss": ">=3.4.0" } }, { "name": "navbar", "package": "@nextui-org/navbar", - "version": "2.1.0", + "version": "2.2.4", "docs": "https://nextui.org/docs/components/navbar", "description": "A responsive navigation header positioned on top side of your page that includes support for branding, links, navigation, collapse and more.", "status": "stable", @@ -1899,15 +1899,15 @@ "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1", - "@nextui-org/theme": ">=2.3.0-beta.0", - "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.4.0", + "@nextui-org/system": ">=2.4.0", "tailwindcss": ">=3.4.0" } }, { "name": "pagination", "package": "@nextui-org/pagination", - "version": "2.1.0", + "version": "2.2.4", "docs": "https://nextui.org/docs/components/pagination", "description": "The Pagination component allows you to display active page and navigate between multiple pages.", "status": "stable", @@ -1915,22 +1915,22 @@ "peerDependencies": { "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", - "@nextui-org/theme": ">=2.3.0-beta.0", - "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.4.0", + "@nextui-org/system": ">=2.4.0", "tailwindcss": ">=3.4.0" } }, { "name": "popover", "package": "@nextui-org/popover", - "version": "2.2.0", + "version": "2.3.4", "docs": "https://nextui.org/docs/components/popover", "description": "A popover is an overlay element positioned relative to a trigger.", "status": "stable", "style": "", "peerDependencies": { - "@nextui-org/system": ">=2.3.0-beta.0", - "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.4.0", + "@nextui-org/theme": ">=2.4.0", "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1", "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", @@ -1940,7 +1940,7 @@ { "name": "progress", "package": "@nextui-org/progress", - "version": "2.1.0", + "version": "2.2.4", "docs": "https://nextui.org/docs/components/progress", "description": "Progress bars show either determinate or indeterminate progress of an operation over time.", "status": "stable", @@ -1948,15 +1948,15 @@ "peerDependencies": { "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", - "@nextui-org/theme": ">=2.3.0-beta.0", - "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.4.0", + "@nextui-org/system": ">=2.4.0", "tailwindcss": ">=3.4.0" } }, { "name": "radio", "package": "@nextui-org/radio", - "version": "2.2.0", + "version": "2.3.4", "docs": "https://nextui.org/docs/components/radio", "description": "Radios allow users to select a single option from a list of mutually exclusive options.", "status": "stable", @@ -1964,15 +1964,15 @@ "peerDependencies": { "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", - "@nextui-org/theme": ">=2.3.0-beta.0", - "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.4.0", + "@nextui-org/system": ">=2.4.0", "tailwindcss": ">=3.4.0" } }, { "name": "ripple", "package": "@nextui-org/ripple", - "version": "2.1.0", + "version": "2.2.3", "docs": "https://nextui.org/docs/components/ripple", "description": "A simple implementation to display a ripple animation when the source component is clicked", "status": "stable", @@ -1981,15 +1981,15 @@ "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1", - "@nextui-org/theme": ">=2.3.0-beta.0", - "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.4.0", + "@nextui-org/system": ">=2.4.0", "tailwindcss": ">=3.4.0" } }, { "name": "scroll-shadow", "package": "@nextui-org/scroll-shadow", - "version": "2.2.0", + "version": "2.3.3", "docs": "https://nextui.org/docs/components/scroll-shadow", "description": "A component that applies top and bottom shadows when content overflows on scroll.", "status": "stable", @@ -1997,22 +1997,22 @@ "peerDependencies": { "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", - "@nextui-org/theme": ">=2.3.0-beta.0", - "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.4.0", + "@nextui-org/system": ">=2.4.0", "tailwindcss": ">=3.4.0" } }, { "name": "select", "package": "@nextui-org/select", - "version": "2.3.0", + "version": "2.4.4", "docs": "https://nextui.org/docs/components/select", "description": "A select displays a collapsible list of options and allows a user to select one of them.", "status": "updated", "style": "", "peerDependencies": { - "@nextui-org/system": ">=2.3.0-beta.0", - "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/system": ">=2.4.0", + "@nextui-org/theme": ">=2.4.0", "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1", "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", @@ -2022,7 +2022,7 @@ { "name": "skeleton", "package": "@nextui-org/skeleton", - "version": "2.1.0", + "version": "2.2.3", "docs": "https://nextui.org/docs/components/skeleton", "description": "Skeleton is used to display the loading state of some component.", "status": "stable", @@ -2030,15 +2030,15 @@ "peerDependencies": { "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", - "@nextui-org/theme": ">=2.3.0-beta.0", - "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.4.0", + "@nextui-org/system": ">=2.4.0", "tailwindcss": ">=3.4.0" } }, { "name": "slider", "package": "@nextui-org/slider", - "version": "2.3.0", + "version": "2.4.4", "docs": "https://nextui.org/docs/components/slider", "description": "A slider allows a user to select one or more values within a range.", "status": "stable", @@ -2046,15 +2046,15 @@ "peerDependencies": { "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", - "@nextui-org/theme": ">=2.3.0-beta.0", - "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.4.0", + "@nextui-org/system": ">=2.4.0", "tailwindcss": ">=3.4.0" } }, { "name": "snippet", "package": "@nextui-org/snippet", - "version": "2.1.0", + "version": "2.2.5", "docs": "https://nextui.org/docs/components/snippet", "description": "Display a snippet of copyable code for the command line.", "status": "stable", @@ -2063,15 +2063,15 @@ "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1", - "@nextui-org/theme": ">=2.3.0-beta.0", - "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.4.0", + "@nextui-org/system": ">=2.4.0", "tailwindcss": ">=3.4.0" } }, { "name": "spacer", "package": "@nextui-org/spacer", - "version": "2.1.0", + "version": "2.2.4", "docs": "https://nextui.org/docs/components/spacer", "description": "A flexible spacer component designed to create consistent spacing and maintain alignment in your layout.", "status": "stable", @@ -2079,14 +2079,14 @@ "peerDependencies": { "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", - "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.4.0", "tailwindcss": ">=3.4.0" } }, { "name": "spinner", "package": "@nextui-org/spinner", - "version": "2.1.0", + "version": "2.2.4", "docs": "https://nextui.org/docs/components/spinner", "description": "Loaders express an unspecified wait time or display the length of a process.", "status": "stable", @@ -2094,14 +2094,14 @@ "peerDependencies": { "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", - "@nextui-org/theme": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.4.0", "tailwindcss": ">=3.4.0" } }, { "name": "switch", "package": "@nextui-org/switch", - "version": "2.1.0", + "version": "2.2.4", "docs": "https://nextui.org/docs/components/switch", "description": "A switch is similar to a checkbox, but represents on/off values as opposed to selection.", "status": "updated", @@ -2109,15 +2109,15 @@ "peerDependencies": { "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", - "@nextui-org/theme": ">=2.3.0-beta.0", - "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.4.0", + "@nextui-org/system": ">=2.4.0", "tailwindcss": ">=3.4.0" } }, { "name": "table", "package": "@nextui-org/table", - "version": "2.1.0", + "version": "2.2.4", "docs": "https://nextui.org/docs/components/table", "description": "Tables are used to display tabular data using rows and columns. ", "status": "stable", @@ -2125,15 +2125,15 @@ "peerDependencies": { "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", - "@nextui-org/theme": ">=2.3.0-beta.0", - "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.4.0", + "@nextui-org/system": ">=2.4.0", "tailwindcss": ">=3.4.0" } }, { "name": "tabs", "package": "@nextui-org/tabs", - "version": "2.1.0", + "version": "2.2.4", "docs": "https://nextui.org/docs/components/tabs", "description": "Tabs organize content into multiple sections and allow users to navigate between them.", "status": "stable", @@ -2142,15 +2142,15 @@ "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1", - "@nextui-org/theme": ">=2.3.0-beta.0", - "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.4.0", + "@nextui-org/system": ">=2.4.0", "tailwindcss": ">=3.4.0" } }, { "name": "tooltip", "package": "@nextui-org/tooltip", - "version": "2.1.0", + "version": "2.2.4", "docs": "https://nextui.org/docs/components/tooltip", "description": "A React Component for rendering dynamically positioned Tooltips", "status": "stable", @@ -2159,15 +2159,15 @@ "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", "framer-motion": ">=11.5.6 || >=12.0.0-alpha.1", - "@nextui-org/theme": ">=2.3.0-beta.0", - "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.4.0", + "@nextui-org/system": ">=2.4.0", "tailwindcss": ">=3.4.0" } }, { "name": "user", "package": "@nextui-org/user", - "version": "2.1.0", + "version": "2.2.4", "docs": "https://nextui.org/docs/components/user", "description": "Flexible User Profile Component.", "status": "stable", @@ -2175,11 +2175,11 @@ "peerDependencies": { "react": ">=18 || >=19.0.0-rc.0", "react-dom": ">=18 || >=19.0.0-rc.0", - "@nextui-org/theme": ">=2.3.0-beta.0", - "@nextui-org/system": ">=2.3.0-beta.0", + "@nextui-org/theme": ">=2.4.0", + "@nextui-org/system": ">=2.4.0", "tailwindcss": ">=3.4.0" } } ], - "canaryVersion": "0.0.0-canary-20241205120225" + "canaryVersion": "0.0.0-canary-20241209160218" } diff --git a/src/scripts/helpers.ts b/src/scripts/helpers.ts index 868c389..9f38214 100644 --- a/src/scripts/helpers.ts +++ b/src/scripts/helpers.ts @@ -39,6 +39,7 @@ export type ComponentsJson = { interface UpdateComponentsOptions { beta?: boolean; canary?: boolean; + fetchBasic?: boolean; } /** @@ -59,11 +60,11 @@ export function compareVersions(version1 = '', version2 = '') { } export async function updateComponents(options?: UpdateComponentsOptions) { - const {beta = store.beta, canary = store.canary} = options ?? {}; + const {beta = store.beta, canary = store.canary, fetchBasic = false} = options ?? {}; if (!existsSync(COMPONENTS_PATH)) { // First time download the latest date from net - await autoUpdateComponents({beta, canary}); + await autoUpdateComponents({beta, canary, fetchBasic}); return; } @@ -89,6 +90,7 @@ export async function updateComponents(options?: UpdateComponentsOptions) { betaVersion: latestBetaVersion, canary, canaryVersion: latestCanaryVersion, + fetchBasic, latestVersion }); } @@ -169,12 +171,13 @@ export async function autoUpdateComponents( } & UpdateComponentsOptions ) { let {betaVersion, canaryVersion, latestVersion} = options; - const {beta, canary} = options; + const {beta, canary, fetchBasic} = options; const existComponentsPath = existsSync(COMPONENTS_PATH); [latestVersion, betaVersion, canaryVersion] = await Promise.all([ // If the components.json is not exist, then we need to download the latest version - ((!beta && !canary) || !existComponentsPath) && (latestVersion || getStore('latestVersion')), + ((!beta && !canary) || !existComponentsPath || fetchBasic) && + (latestVersion || getStore('latestVersion')), beta && (betaVersion || getStore('betaVersion')), canary && (canaryVersion || getStore('canaryVersion')) ] as string[]); diff --git a/src/scripts/update/update-components.ts b/src/scripts/update/update-components.ts index 6290068..2ea7421 100644 --- a/src/scripts/update/update-components.ts +++ b/src/scripts/update/update-components.ts @@ -10,5 +10,5 @@ if (!isGithubAction) { store.beta = true; // Update canary components store.canary = true; - updateComponents(); + updateComponents({fetchBasic: true}); } From 7d47318bee4805ffbf514ace49859122e388edd4 Mon Sep 17 00:00:00 2001 From: winches <329487092@qq.com> Date: Tue, 10 Dec 2024 09:48:29 +0800 Subject: [PATCH 09/10] fix: ensure components update --- src/scripts/helpers.ts | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/src/scripts/helpers.ts b/src/scripts/helpers.ts index 9f38214..d5612b1 100644 --- a/src/scripts/helpers.ts +++ b/src/scripts/helpers.ts @@ -182,8 +182,14 @@ export async function autoUpdateComponents( canary && (canaryVersion || getStore('canaryVersion')) ] as string[]); + const originalComponentsJson = ( + existComponentsPath ? JSON.parse(readFileSync(COMPONENTS_PATH, 'utf-8')) : {components: []} + ) as ComponentsJson; + const [components, betaComponents, canaryComponents] = await Promise.all([ - latestVersion ? downloadFile({url: getUnpkgUrl(latestVersion)}) : Promise.resolve([]), + latestVersion + ? downloadFile({url: getUnpkgUrl(latestVersion)}) + : Promise.resolve(originalComponentsJson.components), betaVersion ? downloadFile({ successText: 'Beta components updated successfully!', @@ -198,29 +204,20 @@ export async function autoUpdateComponents( : Promise.resolve([]) ]); - const originalComponentsJson = ( - existComponentsPath ? JSON.parse(readFileSync(COMPONENTS_PATH, 'utf-8')) : {components} - ) as ComponentsJson; - - const filterMissingComponents = beta - ? betaComponents.filter( - (component) => !originalComponentsJson.components?.find((c) => c.name === component.name) - ) - : canary - ? canaryComponents.filter( - (component) => !originalComponentsJson.components?.find((c) => c.name === component.name) - ) - : []; + const conditionalComponents = beta ? betaComponents : canary ? canaryComponents : []; + const filterMissingComponents = conditionalComponents.filter( + (component) => !components?.find((c) => c.name === component.name) + ); // Add missing beta/canary components to components - components.push(...(filterMissingComponents ?? [])); + components.concat(filterMissingComponents ?? []); const componentsJson: ComponentsJson = { ...originalComponentsJson, ...(beta ? {betaComponents, betaVersion} : {}), ...(canary ? {canaryComponents, canaryVersion} : {}), ...(latestVersion ? {version: latestVersion} : {}), - components: originalComponentsJson.components.concat(filterMissingComponents ?? []) + components }; writeFileSync(COMPONENTS_PATH, JSON.stringify(componentsJson, null, 2), 'utf-8'); From d675fb977bd0201d29c00eda889498f2f223558d Mon Sep 17 00:00:00 2001 From: winches <329487092@qq.com> Date: Tue, 10 Dec 2024 09:51:06 +0800 Subject: [PATCH 10/10] feat: update comment --- src/scripts/update/update-components.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/scripts/update/update-components.ts b/src/scripts/update/update-components.ts index 2ea7421..d30c49d 100644 --- a/src/scripts/update/update-components.ts +++ b/src/scripts/update/update-components.ts @@ -3,8 +3,9 @@ import {store} from 'src/constants/store'; import {initCache} from '../cache/cache'; import {isGithubAction, updateComponents} from '../helpers'; +// Won't run on GitHub Actions if (!isGithubAction) { - // Won't run on GitHub Actions + // Force to update cache initCache(true); // Update beta components store.beta = true;