diff --git a/packages/cli-t/dist/index.d.ts b/packages/cli-t/dist/index.d.ts new file mode 100755 index 0000000..908ba84 --- /dev/null +++ b/packages/cli-t/dist/index.d.ts @@ -0,0 +1 @@ +#!/usr/bin/env node diff --git a/packages/cli-t/dist/index.js b/packages/cli-t/dist/index.js new file mode 100755 index 0000000..317877d --- /dev/null +++ b/packages/cli-t/dist/index.js @@ -0,0 +1,4 @@ +#!/usr/bin/env node +import{Command as yt}from"commander";var f={name:"duck-ui",description:"This is the main file of the duck-ui CLI application written with TypeScript",version:"1.0.0"};import{Command as _t}from"commander";var C={name:"init",description:"init the project",options:{option_1:{flags:"-y, --yes",description:"skip confirmation prompt.",defaultValue:!1},option_2:{flags:"-d, --defaults,",description:"use default configuration.",defaultValue:!1},option_3:{flags:"-c, --cwd ",description:"the working directory. defaults to the current directory.",defaultValue:process.cwd()},option_4:{flags:"-s, --silent",description:"silent mode",defaultValue:!1},option_5:{flags:"-f, --force",description:"will force and overwrite old configurations.",defaultValue:!1},option_6:{flags:"-sd, --src-dir ",description:"the source directory. defaults to the current directory.",defaultValue:process.cwd()}}};import gt from"path";import{z as a}from"zod";var T=a.object({yes:a.boolean().default(!1),defaults:a.boolean().default(!1),cwd:a.string().default(process.cwd()),slint:a.boolean().default(!1),force:a.boolean().default(!1),srcDir:a.string().default(process.cwd())});var l=["**/node_modules","**/.git","**/dist","**/.next","**/build","**/coverage","**/public"],R={info:"You need to install TailwindCss:"};import $t from"fs-extra";import ot from"fast-glob";import s from"kleur";import F from"log-symbols";var{error:B,warning:K,info:X,success:q}=F,c={error(...t){return console.log(s.red([B,"ERROR:"].join("")),s.red(t.join(" "))),this},warn(...t){return console.log(s.yellow([K,"WARN:"].join("")),s.yellow(t.join(" "))),this},info(...t){return console.log(s.green([X,"INFO:"].join("")),s.green(t.join(" "))),this},success(...t){return console.log(s.green([q,"SUCCESS:"].join("")),s.green(t.join(" "))),this},break(){return console.log(""),this}};import{cyan as H,green as Q,red as Z,yellow as tt}from"kleur/colors";var p={error:Z,warn:tt,success:Q,info:H};async function S(t){let o=ot.globSync("tailwind.config.*",{cwd:t,deep:3,ignore:l});return o.length?(console.log(o),!0):!1}import{createMatchPath as Mt}from"tsconfig-paths";import Xt from"fast-glob";import et from"fs-extra";import nt from"path";import{loadConfig as to}from"tsconfig-paths";function I(){let t=nt.join("package.json");return JSON.parse(et.readFileSync(t,"utf8"))}import{loadConfig as $o}from"tsconfig-paths";import{cosmiconfig as it}from"cosmiconfig";var rt=it("duck-ui",{searchPlaces:["duck-ui.config.js","duck-ui.config.ts"]});import{z as e}from"zod";var E=e.object({$schema:e.string().optional(),style:e.string(),rsc:e.coerce.boolean().default(!1),tsx:e.coerce.boolean().default(!0),tailwind:e.object({config:e.string(),css:e.string(),baseColor:e.string(),cssVariables:e.boolean().default(!0),prefix:e.string().default("").optional()}),aliases:e.object({components:e.string(),hooks:e.string().optional(),pages:e.string().optional(),utils:e.string(),lib:e.string().optional(),ui:e.string().optional()})}).strict(),st=E.extend({resolvedPaths:e.object({tailwindConfig:e.string(),tailwindCss:e.string(),utils:e.string(),components:e.string(),ui:e.string()})});import at from"fast-glob";var v={type:"NEXT_JS",detect:async t=>!!(await at.glob("**/*",{cwd:t,deep:3,ignore:l})).find(r=>r.includes("next.config"))};var d=(i=>(i.NEXT_JS="Next.js",i.VITE="Vite",i.CREATE_REACT_APP="Create React App",i.UNKNOWN="Unknown",i))(d||{}),P=[v];async function g(t){for(let o of P)if(await o.detect(t))return o.type;return"UNKNOWN"}import{z as ct}from"zod";function O(t){return Object.values(t)}var pt=O(d),Co=ct.enum([...pt]);import{z as N}from"zod";var lt=N.string().min(1,"Path must be a non-empty string"),ft=N.string().refine(t=>/\/chat\/b\//.test(t),{message:"The URL must contain /chat/b/ in the pathname"});import dt from"prompts";var V=[{type:"confirm",name:"tailwind",message:`Would you like to use ${p.info("TailwindCSS")}`,initial:!1,active:"yes",inactive:"no"}],D=["tailwindcss","postcss","autoprefixer"],U=["tailwindcss","init","-p"];import{z as $}from"zod";var G=$.object({tailwind:$.boolean({message:"You have to pick one option",description:"Would you like to use TailwindCSS? (yes/no) -default: no"}).default(!1)});import mt from"ora";function m(t,o){return mt({color:"yellow",text:t,isSilent:o?.silent})}import{execa as J}from"execa";import{detect as ut}from"@antfu/ni";async function _(t){let o=await ut({programmatic:!0,cwd:t});return o==="yarn@berry"?"yarn":o==="pnpm@6"?"pnpm":o||"npm"}async function A(t,o){let n=o??await _(t);return n==="pnpm"?"pnpm dlx":n==="bun"?"bunx":"npx"}async function L(t,o){let n=m(p.info("Installing TailwindCSS...")).start(),r=await _(t),{failed:i}=await J(r,[r!=="npm"?"install":"add",...D],{cwd:t,shell:!0});if(i)return n.fail();let u=await A(t,r),{failed:j}=await J(u,[...U],{cwd:t,shell:!0});if(j)return n.fail();c.break(),n.succeed()}async function z(t){let o=m(`Checking if TailwindCSS is installed... +`)?.start();if(await S(t))return o.stopAndPersist({text:p.success("TailwindCSS is installed!")}),o?.succeed(),null;o?.fail(),c.info(...Object.values(R)).break();let r=await dt(V),{tailwind:i}=G.parse(r);if(!i)return null;let u=await g(t),j=await L(t,u);return i}async function W(t){let o=T.parse(t),n=gt.resolve(o.cwd),r=await z(n)}var{name:xt,description:wt,options:ht}=C,{option_1:x,option_2:w,option_3:h,option_4:y,option_5:k,option_6:b}=ht;function M(){let t=new _t(xt);return t.description(wt).option(x.flags,x.description,x.defaultValue).option(w.flags,w.description,w.defaultValue).option(h.flags,h.description,h.defaultValue).option(y.flags,y.description,y.defaultValue).option(k.flags,k.description,k.defaultValue).option(b.flags,b.description,b.defaultValue).action(W),t}function Y(){let t=new yt,o=I();t.name(o.name||f.name),t.description(o.description||f.description),t.version(o.version||f.version),t.addCommand(M()),t.parse()}process.on("SIGINT",()=>process.exit(0));process.on("SIGTERM",()=>process.exit(0));Y(); +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/packages/cli-t/dist/index.js.map b/packages/cli-t/dist/index.js.map new file mode 100644 index 0000000..bf1a07a --- /dev/null +++ b/packages/cli-t/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["../src/main/main.ts","../src/main/main.constants.ts","../src/commands/init/init.ts","../src/commands/init/init.constants.ts","../src/commands/init/init.lib.ts","../src/commands/init/init.dto.ts","../src/utils/get-project-info/get-project-info.constants.ts","../src/utils/checkers/checkers.ts","../src/utils/text-styling/logger.ts","../src/utils/text-styling/highlighter.ts","../src/utils/resolve-import/resolve-import.ts","../src/utils/get-project-info/get-project-info.ts","../src/utils/get-project-config/get-project-config.ts","../src/utils/get-project-config/get-project-config.constants.ts","../src/utils/get-project-config/get-project-config.dto.ts","../src/utils/get-project-type/get-project-type.lib.ts","../src/utils/get-project-type/get-project-type.constants.ts","../src/utils/get-project-type/get-project-type.ts","../src/utils/get-project-type/get-project-type.dto.ts","../src/utils/transformers/transformers.ts","../src/utils/url-mutating/url-mutating.dto.ts","../src/utils/pref-light-tailwindcss/pref-light-tailwindcss.ts","../src/utils/pref-light-tailwindcss/pref-light-tailwindcss.constants.ts","../src/utils/pref-light-tailwindcss/pref-light-tailwindcss.dto.ts","../src/utils/spinner.ts","../src/utils/pref-light-tailwindcss/pref-light-tailwindcss.lib.ts","../src/utils/get-package-manager/get-package-manager.ts","../src/index.ts"],"sourcesContent":["import { Command } from 'commander'\nimport { config } from './main.constants'\nimport { init_command } from '../commands/init'\nimport { getPackageJson } from '../utils'\n\nexport function init() {\n const duck_ui = new Command()\n const packageJson = getPackageJson()\n\n duck_ui.name(packageJson.name || config.name)\n duck_ui.description(packageJson.description || config.description)\n duck_ui.version(packageJson.version || config.version)\n duck_ui.addCommand(init_command())\n\n duck_ui.parse()\n}\n","export const config = {\n name: 'duck-ui',\n description:\n 'This is the main file of the duck-ui CLI application written with TypeScript',\n version: '1.0.0'\n}\n\nexport const REGISTRY_URL = 'https://duckui.vercel.app/registry'\n","import { Command } from 'commander'\nimport { init_command_config } from './init.constants'\nimport { init_command_action } from './init.lib'\n\nconst { name, description, options } = init_command_config\nconst { option_1, option_2, option_3, option_4, option_5, option_6 } = options\n\nexport function init_command(): Command {\n const init_command = new Command(name)\n\n init_command\n .description(description)\n .option(option_1.flags, option_1.description, option_1.defaultValue)\n .option(option_2.flags, option_2.description, option_2.defaultValue)\n .option(option_3.flags, option_3.description, option_3.defaultValue)\n .option(option_4.flags, option_4.description, option_4.defaultValue)\n .option(option_5.flags, option_5.description, option_5.defaultValue)\n .option(option_6.flags, option_6.description, option_6.defaultValue)\n .action(init_command_action)\n\n return init_command\n}\n","import { InitCommandConfig } from './init.types'\n\nexport const init_command_config: InitCommandConfig = {\n name: 'init',\n description: 'init the project',\n options: {\n option_1: {\n flags: '-y, --yes',\n description: 'skip confirmation prompt.',\n defaultValue: false\n },\n option_2: {\n flags: '-d, --defaults,',\n description: 'use default configuration.',\n defaultValue: false\n },\n option_3: {\n flags: '-c, --cwd ',\n description: 'the working directory. defaults to the current directory.',\n defaultValue: process.cwd()\n },\n option_4: {\n flags: '-s, --silent',\n description: 'silent mode',\n defaultValue: false\n },\n option_5: {\n flags: '-f, --force',\n description: 'will force and overwrite old configurations.',\n defaultValue: false\n },\n option_6: {\n flags: '-sd, --src-dir ',\n description: 'the source directory. defaults to the current directory.',\n defaultValue: process.cwd()\n }\n }\n}\n","import path from 'path'\nimport { init_options_schema, InitOptions } from './init.dto'\nimport {\n checkTailwindCssInstalled,\n checkTypeScriptInstalled,\n get_project_config,\n get_project_type,\n pref_light_tailwindcss\n} from '@/src/utils'\nimport { spinner } from '@/src/utils/spinner'\nimport { REGISTRY_URL } from '@/src/main'\n\nexport async function init_command_action(opt: InitOptions) {\n const options = init_options_schema.parse(opt)\n const cwd = path.resolve(options.cwd)\n\n const tailwind = await pref_light_tailwindcss(cwd)\n\n // const config = await get_project_config(cwd)\n\n // console.log(config)\n}\n\n// export async function init_command() {}\n// function isUrl(path: string) {\n// try {\n// new URL(path)\n// return true\n// } catch (error) {\n// return false\n// }\n// }\n//\n// function getRegistryUrl(path: string) {\n// if (isUrl(path)) {\n// // If the url contains /chat/b/, we assume it's the v0 registry.\n// //NOTE: We need to add the /json suffix if it's missing.\n// const url = new URL(path)\n// if (url.pathname.match(/\\/chat\\/b\\//) && !url.pathname.endsWith('/json')) {\n// url.pathname = `${url.pathname}/json`\n// }\n//\n// return url.toString()\n// }\n//\n// return `${REGISTRY_URL}/${path}`\n// }\n","import { z } from 'zod'\n\nexport const init_options_schema = z.object({\n yes: z.boolean().default(false),\n defaults: z.boolean().default(false),\n cwd: z.string().default(process.cwd()),\n slint: z.boolean().default(false),\n force: z.boolean().default(false),\n srcDir: z.string().default(process.cwd())\n})\n\nexport type InitOptions = z.infer\n","export const IGNORED_DIRECTORIES = [\n '**/node_modules',\n '**/.git',\n '**/dist',\n '**/.next',\n '**/build',\n '**/coverage',\n '**/public'\n]\n\nexport const tailwindCssInstallationGuide = {\n info: 'You need to install TailwindCss:'\n}\n","import {\n IGNORED_DIRECTORIES,\n tailwindCssInstallationGuide\n} from '../get-project-info/get-project-info.constants'\nimport fs from 'fs-extra'\nimport path from 'path'\nimport fg from 'fast-glob'\nimport { logger } from '../text-styling'\n\n// Check if TypeScript is installed\nexport async function checkTypeScriptInstalled(cwd: string) {\n return fs.pathExists(path.resolve(cwd, 'tsconfig.json'))\n}\n\n// Check if TailwindCss is installed\nexport async function checkTailwindCssInstalled(cwd: string) {\n const tailwindcss = fg.globSync('tailwind.config.*', {\n cwd,\n deep: 3,\n ignore: IGNORED_DIRECTORIES\n })\n\n if (!tailwindcss.length) return false\n console.log(tailwindcss)\n return true\n}\n\n// Check if the working directory exists\nexport function checkDirectoryExist(cwd: string): typeof logger | undefined {\n if (!fs.lstatSync(cwd).isDirectory()) {\n return logger.error(`The working directory ${cwd} does not exist.`)\n }\n}\n\n// Check if the project is valid\nexport function checkProjectIsValid(cwd: string): void {\n // Check if the cwd exists && it's a directory\n checkDirectoryExist(cwd)\n\n // Check TailwindCss is configured\n checkTailwindCssInstalled(cwd)\n}\n","import kleur from 'kleur'\nimport logSymbols from 'log-symbols'\nconst { error, warning, info, success } = logSymbols\n\nexport const logger = {\n error(...args: unknown[]) {\n console.log(\n kleur.red([error, 'ERROR:'].join('')),\n kleur.red(args.join(' '))\n )\n return this\n },\n warn(...args: unknown[]) {\n console.log(\n kleur.yellow([warning, 'WARN:'].join('')),\n kleur.yellow(args.join(' '))\n )\n return this\n },\n info(...args: unknown[]) {\n console.log(\n kleur.green([info, 'INFO:'].join('')),\n kleur.green(args.join(' '))\n )\n return this\n },\n success(...args: unknown[]) {\n console.log(\n kleur.green([success, 'SUCCESS:'].join('')),\n kleur.green(args.join(' '))\n )\n return this\n },\n break() {\n console.log('')\n return this\n }\n}\n","import { cyan, green, red, yellow } from 'kleur/colors'\n\nexport const highlighter = {\n error: red,\n warn: yellow,\n success: green,\n info: cyan\n}\n","import { createMatchPath, type ConfigLoaderSuccessResult } from 'tsconfig-paths'\n\nexport async function resolve_import(\n importPath: string,\n config: Pick\n) {\n return createMatchPath(config.absoluteBaseUrl, config.paths)(\n importPath,\n undefined,\n () => true,\n ['.ts', '.tsx']\n )\n}\n","import fg from 'fast-glob'\nimport fs from 'fs-extra'\nimport { IGNORED_DIRECTORIES } from './get-project-info.constants'\nimport path from 'path'\nimport { loadConfig } from 'tsconfig-paths'\nimport { type PackageJson } from 'type-fest'\n\n// Get TailwindCss File\nexport async function get_tailwindcss_file(cwd: string) {\n const files = fg.sync(['**/*.css', '**/*.scss', '**/*.sass'], {\n cwd,\n deep: 3,\n ignore: IGNORED_DIRECTORIES\n })\n\n if (!files.length) {\n return null\n }\n\n for (const file of files) {\n const content = await fs.readFile(path.resolve(cwd, file), 'utf8')\n\n if (\n content.includes('@tailwind base') ||\n content.includes('@tailwind components') ||\n content.includes('@tailwind utilities')\n ) {\n return file\n }\n }\n\n return null\n}\n\n// Get Ts Config Alias Prefix\nexport async function get_ts_config_alias_prefix(cwd: string) {\n const tsConfig = loadConfig(cwd)\n\n if (tsConfig.resultType === 'failed' || !tsConfig.paths) {\n return null\n }\n\n for (const [alias, paths] of Object.entries(tsConfig.paths)) {\n if (paths.includes('./src/*') || paths.includes('./*')) {\n return alias.at(0)\n }\n }\n\n return null\n}\n\n// Get package.json\nexport function getPackageJson(): PackageJson {\n const packageJsonPath = path.join('package.json')\n\n return JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'))\n}\n","import { loadConfig } from 'tsconfig-paths'\nimport { explorer } from './get-project-config.constants'\nimport { resolve_import } from '../resolve-import'\nimport {\n config_cchema,\n raw_config_schema,\n RawConfigType\n} from './get-project-config.dto'\nimport path from 'path'\nimport {\n get_tailwindcss_file,\n get_ts_config_alias_prefix\n} from '../get-project-info'\nimport { checkTypeScriptInstalled } from '../checkers'\nimport { logger } from '../text-styling'\nimport { get_project_type } from '../get-project-type'\n\nexport async function get_raw_config(\n cwd: string\n): Promise {\n try {\n const rawConfig = await explorer.search(cwd)\n if (!rawConfig) {\n return null\n }\n\n return raw_config_schema.parse(rawConfig.config)\n } catch (error) {\n logger.error(`Invalid configuration found in ${cwd}/components.json.`)\n process.exit(1)\n }\n}\n\nexport async function get_config(cwd: string) {\n const config = await get_raw_config(cwd)\n\n if (!config) {\n return null\n }\n\n return await resolve_config_paths(cwd, config)\n}\n\n// Resolve Config Paths\nexport async function resolve_config_paths(cwd: string, config: RawConfigType) {\n const ts_config = loadConfig(cwd)\n\n if (ts_config.resultType === 'failed') {\n return logger.error(\n `Failed to leaod ${config.tsx ? 'tsconfig' : 'jsconfig'}.json. ${ts_config.message ?? ''}`.trim()\n )\n }\n\n return config_cchema.parse({\n ...config,\n resolvedPaths: {\n tailwindConfig: path.resolve(cwd, config.tailwind.config),\n tailwindCss: path.resolve(cwd, config.tailwind.css),\n utils: await resolve_import(config.aliases.utils, ts_config),\n components: await resolve_import(config.aliases.components, ts_config),\n ui: config.aliases.ui\n ? await resolve_import(config.aliases.ui, ts_config)\n : await resolve_import(config.aliases.components, ts_config)\n }\n })\n}\n\nexport async function get_project_config(cwd: string) {\n const project_config = get_config(cwd)\n\n if (project_config) {\n return project_config\n }\n\n const project_type = await get_project_type(cwd)\n const tailwindcss_file = await get_tailwindcss_file(cwd)\n const ts_config_alias_prefix = await get_ts_config_alias_prefix(cwd)\n\n if (!project_type || !tailwindcss_file || !ts_config_alias_prefix) {\n return null\n }\n\n const is_tsx = await checkTypeScriptInstalled(cwd)\n\n const config: RawConfigType = {\n $schema: 'https://duckui.vercel.app/schema.json',\n rsc: ['next-app', 'next-app-src'].includes(project_type),\n tsx: is_tsx,\n style: 'default',\n tailwind: {\n config: is_tsx ? 'tailwind.config.ts' : 'tailwind.config.js',\n baseColor: 'zinc',\n css: tailwindcss_file,\n cssVariables: true,\n prefix: ''\n },\n aliases: {\n utils: `${ts_config_alias_prefix}/lib/utils`,\n components: `${ts_config_alias_prefix}/components`\n }\n }\n\n return resolve_config_paths(cwd, config)\n}\n","import { cosmiconfig } from 'cosmiconfig'\n\nexport const explorer = cosmiconfig('duck-ui', {\n searchPlaces: ['duck-ui.config.js', 'duck-ui.config.ts']\n})\n","import { z } from 'zod'\n\nexport const raw_config_schema = z\n .object({\n $schema: z.string().optional(),\n style: z.string(),\n rsc: z.coerce.boolean().default(false),\n tsx: z.coerce.boolean().default(true),\n tailwind: z.object({\n config: z.string(),\n css: z.string(),\n baseColor: z.string(),\n cssVariables: z.boolean().default(true),\n prefix: z.string().default('').optional()\n }),\n aliases: z.object({\n components: z.string(),\n hooks: z.string().optional(),\n pages: z.string().optional(),\n utils: z.string(),\n lib: z.string().optional(),\n ui: z.string().optional()\n })\n })\n .strict()\n\nexport type RawConfigType = z.infer\n\nexport const config_cchema = raw_config_schema.extend({\n resolvedPaths: z.object({\n tailwindConfig: z.string(),\n tailwindCss: z.string(),\n utils: z.string(),\n components: z.string(),\n ui: z.string()\n })\n})\n","import fg from 'fast-glob'\nimport { Detector } from './get-project-type.types'\nimport { IGNORED_DIRECTORIES } from '../get-project-info'\n\n// Detect NextJs\nexport const detectNextJs: Detector = {\n type: 'NEXT_JS',\n detect: async (cwd: string) => {\n const files = await fg.glob('**/*', {\n cwd,\n deep: 3,\n ignore: IGNORED_DIRECTORIES\n })\n\n const is_nextjs = files.find((file) => file.includes('next.config'))\n\n if (is_nextjs) return true\n return false\n }\n}\n","import { detectNextJs } from './get-project-type.lib'\n\nexport enum ProjectTypeEnum {\n NEXT_JS = 'Next.js',\n VITE = 'Vite',\n CREATE_REACT_APP = 'Create React App',\n UNKNOWN = 'Unknown'\n}\n\n// Gather all detectors in a single array\nexport const detectors = [detectNextJs]\n","import { detectors, ProjectTypeEnum } from './get-project-type.constants'\n\nexport async function get_project_type(\n cwd: string\n): Promise {\n for (const detector of detectors) {\n const isDetected = await detector.detect(cwd)\n if (isDetected) {\n return detector.type\n }\n }\n return 'UNKNOWN'\n}\n","import { z } from 'zod'\nimport { enumToArray } from '../transformers'\nimport { ProjectTypeEnum } from './get-project-type.constants'\n\nexport const project_types = enumToArray(ProjectTypeEnum)\n\nexport const project_types_schema = z.enum([\n ...(project_types as [string, ...string[]])\n])\n\nexport type ProjectType = ProjectTypeEnum\n","export function enumToArray(enumObj: T): T[keyof T][] {\n return Object.values(enumObj) as T[keyof T][]\n}\n","import { z } from 'zod'\n\nexport const pathSchema = z.string().min(1, 'Path must be a non-empty string')\n\nexport const pathnameSchema = z\n .string()\n .refine((val) => /\\/chat\\/b\\//.test(val), {\n message: 'The URL must contain /chat/b/ in the pathname'\n })\n","import { checkTailwindCssInstalled } from '../checkers'\nimport prompts from 'prompts'\nimport { tailwindcss_prompts } from './pref-light-tailwindcss.constants'\nimport { pref_light_options_schema } from './pref-light-tailwindcss.dto'\nimport { get_project_type } from '../get-project-type'\nimport { spinner } from '../spinner'\nimport { highlighter, logger } from '../text-styling'\nimport { tailwindCssInstallationGuide } from '../get-project-info'\nimport { install_tailwindcss } from './pref-light-tailwindcss.lib'\n\nexport async function pref_light_tailwindcss(\n cwd: string\n): Promise {\n const tailwind_spinner = spinner(\n 'Checking if TailwindCSS is installed...\\n'\n )?.start()\n\n const is_tailwind_installed = await checkTailwindCssInstalled(cwd)\n\n if (is_tailwind_installed) {\n tailwind_spinner.stopAndPersist({\n text: highlighter.success('TailwindCSS is installed!')\n })\n tailwind_spinner?.succeed()\n return null\n }\n\n tailwind_spinner?.fail()\n logger.info(...Object.values(tailwindCssInstallationGuide)).break()\n\n const options = await prompts(tailwindcss_prompts)\n const { tailwind } = pref_light_options_schema.parse(options)\n\n if (!tailwind) return null\n\n const type = await get_project_type(cwd)\n const tailwind_installation = await install_tailwindcss(cwd, type)\n\n return tailwind\n}\n","import { PromptObject } from 'prompts'\nimport { highlighter } from '../text-styling'\n\nexport const tailwindcss_prompts: PromptObject[] = [\n {\n type: 'confirm',\n name: 'tailwind',\n message: `Would you like to use ${highlighter.info('TailwindCSS')}`,\n initial: false,\n active: 'yes',\n inactive: 'no'\n }\n]\n\n//NOTE: willing to support more when we have more frameworks to support with duck-ui\nexport const tailwindcss_dependencies = [\n 'tailwindcss',\n 'postcss',\n 'autoprefixer'\n]\n\nexport const tailwindcss_init = ['tailwindcss', 'init', '-p']\n","import { z } from 'zod'\n\nexport const pref_light_options_schema = z.object({\n tailwind: z\n .boolean({\n message: 'You have to pick one option',\n description: 'Would you like to use TailwindCSS? (yes/no) -default: no'\n })\n .default(false)\n})\n","import ora, { type Options } from 'ora'\n\nexport function spinner(\n text: Options['text'],\n options?: {\n silent?: boolean\n }\n) {\n return ora({\n color: 'yellow',\n text,\n isSilent: options?.silent\n })\n}\n","import { execa } from 'execa'\nimport { get_package_manager, getPackageRunner } from '../get-package-manager'\nimport { spinner } from '../spinner'\nimport { highlighter, logger } from '../text-styling'\nimport {\n tailwindcss_dependencies,\n tailwindcss_init\n} from './pref-light-tailwindcss.constants'\n\nexport async function install_tailwindcss(cwd: string, type: string) {\n const installSpinner = spinner(\n highlighter.info('Installing TailwindCSS...')\n ).start()\n\n const packageManager = await get_package_manager(cwd)\n const { failed: installation_step_1 } = await execa(\n packageManager,\n [packageManager !== 'npm' ? 'install' : 'add', ...tailwindcss_dependencies],\n {\n cwd: cwd,\n shell: true\n }\n )\n if (installation_step_1) return installSpinner.fail()\n\n const packageRunner = await getPackageRunner(cwd, packageManager)\n const { failed: installation_step_2 } = await execa(\n packageRunner,\n [...tailwindcss_init],\n {\n cwd: cwd,\n shell: true\n }\n )\n if (installation_step_2) return installSpinner.fail()\n\n logger.break()\n installSpinner.succeed()\n}\n","import { Agent, detect } from '@antfu/ni'\n\nexport async function get_package_manager(\n cwd: string\n): Promise> {\n const packageManager = await detect({\n programmatic: true,\n cwd\n })\n\n if (packageManager === 'yarn@berry') return 'yarn'\n if (packageManager === 'pnpm@6') return 'pnpm'\n if (!packageManager) return 'npm'\n\n return packageManager\n}\n\nexport async function getPackageRunner(\n cwd: string,\n pm: Exclude\n): Promise<'pnpm dlx' | 'bunx' | 'npx'> {\n const packageManager = pm ?? (await get_package_manager(cwd))\n\n if (packageManager === 'pnpm') return 'pnpm dlx'\n if (packageManager === 'bun') return 'bunx'\n return 'npx'\n}\n","#!/usr/bin/env node\n// This is the main file of the duck-ui CLI application written with TypeScript\n\nimport { init } from './main'\n\n// INIT START\n\nprocess.on('SIGINT', () => process.exit(0))\nprocess.on('SIGTERM', () => process.exit(0))\n\ninit()\n// INIT END\n"],"mappings":"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","names":["Command","config","Command","init_command_config","path","z","init_options_schema","IGNORED_DIRECTORIES","tailwindCssInstallationGuide","fs","fg","kleur","logSymbols","error","warning","info","success","logger","args","cyan","green","red","yellow","highlighter","checkTailwindCssInstalled","cwd","tailwindcss","fg","IGNORED_DIRECTORIES","createMatchPath","fg","fs","path","loadConfig","getPackageJson","packageJsonPath","path","fs","loadConfig","cosmiconfig","explorer","z","raw_config_schema","config_cchema","fg","detectNextJs","cwd","fg","IGNORED_DIRECTORIES","file","ProjectTypeEnum","detectors","detectNextJs","get_project_type","cwd","detector","detectors","z","enumToArray","enumObj","project_types","enumToArray","ProjectTypeEnum","project_types_schema","z","z","pathSchema","pathnameSchema","val","prompts","tailwindcss_prompts","highlighter","tailwindcss_dependencies","tailwindcss_init","z","pref_light_options_schema","ora","spinner","text","options","execa","detect","get_package_manager","cwd","packageManager","getPackageRunner","pm","install_tailwindcss","cwd","type","installSpinner","spinner","highlighter","packageManager","get_package_manager","installation_step_1","execa","tailwindcss_dependencies","packageRunner","getPackageRunner","installation_step_2","tailwindcss_init","logger","pref_light_tailwindcss","cwd","tailwind_spinner","spinner","checkTailwindCssInstalled","highlighter","logger","tailwindCssInstallationGuide","options","prompts","tailwindcss_prompts","tailwind","pref_light_options_schema","type","get_project_type","tailwind_installation","install_tailwindcss","init_command_action","opt","options","init_options_schema","cwd","path","tailwind","pref_light_tailwindcss","name","description","options","init_command_config","option_1","option_2","option_3","option_4","option_5","option_6","init_command","Command","init_command_action","init","duck_ui","Command","packageJson","getPackageJson","config","init_command","init"]} \ No newline at end of file diff --git a/packages/cli-t/package.json b/packages/cli-t/package.json index 95820bd..6f9fa6e 100644 --- a/packages/cli-t/package.json +++ b/packages/cli-t/package.json @@ -1,28 +1,77 @@ { - "name": "duck-ui", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "keywords": [], - "author": "", - "license": "ISC", - "dependencies": { - "@types/fs-extra": "^11.0.1", - "@types/node": "^17.0.45", - "chalk": "5.2.0", - "commander": "^10.0.0", - "cosmiconfig": "^8.1.3", - "fast-glob": "^3.3.2", - "fs-extra": "^11.1.0", - "globals": "^15.9.0", - "kleur": "^4.1.5", - "log-symbols": "^7.0.0", - "ora": "^6.1.2", - "tsconfig-paths": "^4.2.0", - "type-fest": "^3.8.0", - "zod": "^3.23.8" - } + "name": "duck-ui", + "version": "0.0.2", + "description": "Add components to your apps.", + "publishConfig": { + "access": "public" + }, + "license": "MIT", + "author": "wildduck (https://github.com/wildduck2)", + "repository": { + "type": "git", + "url": "git+https://github.com/gentelduck/ui.git", + "directory": "packages/cli" + }, + "files": [ + "dist" + ], + "keywords": [ + "components", + "ui", + "tailwind", + "radix-ui", + "duck-ui" + ], + "type": "module", + "exports": "./dist/index.js", + "bin": { + "duck-ui": "dist/index.js" + }, + "scripts": { + "dev": "tsup --watch", + "build": "tsup", + "typecheck": "tsc --noEmit", + "clean": "rimraf dist", + "start:dev": "cross-env COMPONENTS_REGISTRY_URL=http://localhost:3003 node dist/index.js", + "start": "node dist/index.js", + "format:write": "prettier --write \"**/*.{ts,tsx,mdx}\" --cache", + "format:check": "prettier --check \"**/*.{ts,tsx,mdx}\" --cache", + "release": "changeset version", + "test": "vitest run" + }, + "dependencies": { + "@antfu/ni": "^0.21.12", + "chalk": "5.2.0", + "commander": "^10.0.1", + "cosmiconfig": "^8.3.6", + "execa": "^9.4.1", + "fast-glob": "^3.3.2", + "fs-extra": "^11.2.0", + "globals": "^15.11.0", + "kleur": "^4.1.5", + "log-symbols": "^7.0.0", + "ora": "^6.3.1", + "prompts": "^2.4.2", + "tsconfig-paths": "^4.2.0", + "zod": "^3.23.8" + }, + "devDependencies": { + "@types/babel__core": "^7.20.1", + "@types/diff": "^5.0.3", + "@types/fs-extra": "^11.0.1", + "@types/lodash.template": "^4.5.1", + "@types/prompts": "^2.4.2", + "rimraf": "^4.1.3", + "tsup": "^6.6.3", + "type-fest": "^3.8.0", + "typescript": "^4.9.3" + }, + "bugs": { + "url": "https://github.com/gentelduck/ui/issues" + }, + "homepage": "https://github.com/gentelduck/ui#readme", + "main": "index.js", + "directories": { + "test": "test" + } } diff --git a/packages/cli-t/src/commands/init/index.ts b/packages/cli-t/src/commands/init/index.ts index 87ee658..7970ca2 100644 --- a/packages/cli-t/src/commands/init/index.ts +++ b/packages/cli-t/src/commands/init/index.ts @@ -2,3 +2,4 @@ export * from './init' export * from './init.constants' export * from './init.lib' export * from './init.dto' +export * from './init.types' diff --git a/packages/cli-t/src/commands/init/init.constants.ts b/packages/cli-t/src/commands/init/init.constants.ts index 0a710b1..66cf4e6 100644 --- a/packages/cli-t/src/commands/init/init.constants.ts +++ b/packages/cli-t/src/commands/init/init.constants.ts @@ -1,19 +1,38 @@ -export const init_command_config = { +import { InitCommandConfig } from './init.types' + +export const init_command_config: InitCommandConfig = { name: 'init', description: 'init the project', - option_1: { - flags: '-y, --yes', - description: 'skip confirmation prompt.', - defaultValue: false - }, - option_2: { - flags: '-d, --defaults,', - description: 'use default configuration.', - defaultValue: false - }, - option_3: { - flags: '-c, --cwd ', - description: 'the working directory. defaults to the current directory.', - defaultValue: process.cwd() + options: { + option_1: { + flags: '-y, --yes', + description: 'skip confirmation prompt.', + defaultValue: false + }, + option_2: { + flags: '-d, --defaults,', + description: 'use default configuration.', + defaultValue: false + }, + option_3: { + flags: '-c, --cwd ', + description: 'the working directory. defaults to the current directory.', + defaultValue: process.cwd() + }, + option_4: { + flags: '-s, --silent', + description: 'silent mode', + defaultValue: false + }, + option_5: { + flags: '-f, --force', + description: 'will force and overwrite old configurations.', + defaultValue: false + }, + option_6: { + flags: '-sd, --src-dir ', + description: 'the source directory. defaults to the current directory.', + defaultValue: process.cwd() + } } } diff --git a/packages/cli-t/src/commands/init/init.dto.ts b/packages/cli-t/src/commands/init/init.dto.ts index b825818..68fd4e3 100644 --- a/packages/cli-t/src/commands/init/init.dto.ts +++ b/packages/cli-t/src/commands/init/init.dto.ts @@ -3,7 +3,10 @@ import { z } from 'zod' export const init_options_schema = z.object({ yes: z.boolean().default(false), defaults: z.boolean().default(false), - cwd: z.string().default(process.cwd()) + cwd: z.string().default(process.cwd()), + slint: z.boolean().default(false), + force: z.boolean().default(false), + srcDir: z.string().default(process.cwd()) }) export type InitOptions = z.infer diff --git a/packages/cli-t/src/commands/init/init.lib.ts b/packages/cli-t/src/commands/init/init.lib.ts index 9fec84d..a11bf68 100644 --- a/packages/cli-t/src/commands/init/init.lib.ts +++ b/packages/cli-t/src/commands/init/init.lib.ts @@ -1,44 +1,46 @@ import path from 'path' import { init_options_schema, InitOptions } from './init.dto' import { - checkTailwindCssInstalled, checkTypeScriptInstalled, - get_project_config + get_project_config, + logger, + pref_light_tailwindcss } from '@/src/utils' -import { spinner } from '@/src/utils/spinner' -import { REGISTRY_URL } from '@/src/main' export async function init_command_action(opt: InitOptions) { const options = init_options_schema.parse(opt) const cwd = path.resolve(options.cwd) - await checkTailwindCssInstalled(cwd) + logger.info({ args: ['Checking for preflight...'] }) + + const typescript = await checkTypeScriptInstalled(cwd) + await pref_light_tailwindcss(cwd, typescript) const config = await get_project_config(cwd) console.log(config) } -export async function init_command() {} -function isUrl(path: string) { - try { - new URL(path) - return true - } catch (error) { - return false - } -} - -function getRegistryUrl(path: string) { - if (isUrl(path)) { - // If the url contains /chat/b/, we assume it's the v0 registry. - //NOTE: We need to add the /json suffix if it's missing. - const url = new URL(path) - if (url.pathname.match(/\/chat\/b\//) && !url.pathname.endsWith('/json')) { - url.pathname = `${url.pathname}/json` - } - - return url.toString() - } - - return `${REGISTRY_URL}/${path}` -} +// export async function init_command() {} +// function isUrl(path: string) { +// try { +// new URL(path) +// return true +// } catch (error) { +// return false +// } +// } +// +// function getRegistryUrl(path: string) { +// if (isUrl(path)) { +// // If the url contains /chat/b/, we assume it's the v0 registry. +// //NOTE: We need to add the /json suffix if it's missing. +// const url = new URL(path) +// if (url.pathname.match(/\/chat\/b\//) && !url.pathname.endsWith('/json')) { +// url.pathname = `${url.pathname}/json` +// } +// +// return url.toString() +// } +// +// return `${REGISTRY_URL}/${path}` +// } diff --git a/packages/cli-t/src/commands/init/init.ts b/packages/cli-t/src/commands/init/init.ts index 89cbbfe..7339409 100644 --- a/packages/cli-t/src/commands/init/init.ts +++ b/packages/cli-t/src/commands/init/init.ts @@ -2,7 +2,8 @@ import { Command } from 'commander' import { init_command_config } from './init.constants' import { init_command_action } from './init.lib' -const { name, description, option_1, option_2, option_3 } = init_command_config +const { name, description, options } = init_command_config +const { option_1, option_2, option_3, option_4, option_5, option_6 } = options export function init_command(): Command { const init_command = new Command(name) @@ -12,6 +13,9 @@ export function init_command(): Command { .option(option_1.flags, option_1.description, option_1.defaultValue) .option(option_2.flags, option_2.description, option_2.defaultValue) .option(option_3.flags, option_3.description, option_3.defaultValue) + .option(option_4.flags, option_4.description, option_4.defaultValue) + .option(option_5.flags, option_5.description, option_5.defaultValue) + .option(option_6.flags, option_6.description, option_6.defaultValue) .action(init_command_action) return init_command diff --git a/packages/cli-t/src/commands/init/init.types.ts b/packages/cli-t/src/commands/init/init.types.ts new file mode 100644 index 0000000..9c91d33 --- /dev/null +++ b/packages/cli-t/src/commands/init/init.types.ts @@ -0,0 +1,11 @@ +export type InitCommandConfig = { + name: string + description: string + options: Record<`option_${number}`, OptionType> +} + +export type OptionType = { + flags: `-${string}, --${string}` + description: string + defaultValue: boolean | string +} diff --git a/packages/cli-t/src/main/main.ts b/packages/cli-t/src/main/main.ts index 2020580..75d0051 100644 --- a/packages/cli-t/src/main/main.ts +++ b/packages/cli-t/src/main/main.ts @@ -7,9 +7,9 @@ export function init() { const duck_ui = new Command() const packageJson = getPackageJson() - duck_ui.name(packageJson.name || config.name) - duck_ui.description(packageJson.description || config.description) - duck_ui.version(packageJson.version || config.version) + duck_ui.name(packageJson?.name || config.name) + duck_ui.description(packageJson?.description || config.description) + duck_ui.version(packageJson?.version || config.version) duck_ui.addCommand(init_command()) duck_ui.parse() diff --git a/packages/cli-t/src/utils/checkers/checkers.ts b/packages/cli-t/src/utils/checkers/checkers.ts index dacfeb3..fce8d0a 100644 --- a/packages/cli-t/src/utils/checkers/checkers.ts +++ b/packages/cli-t/src/utils/checkers/checkers.ts @@ -2,10 +2,10 @@ import { IGNORED_DIRECTORIES, tailwindCssInstallationGuide } from '../get-project-info/get-project-info.constants' -import { logger } from '../logger' import fs from 'fs-extra' import path from 'path' import fg from 'fast-glob' +import { logger } from '../text-styling' // Check if TypeScript is installed export async function checkTypeScriptInstalled(cwd: string) { @@ -20,18 +20,16 @@ export async function checkTailwindCssInstalled(cwd: string) { ignore: IGNORED_DIRECTORIES }) - if (!tailwindcss.length) { - logger.error(`TailwindCss is not configured in this directory.`).break() - logger.info(...Object.values(tailwindCssInstallationGuide)).break() - } - + if (!tailwindcss.length) return false return true } // Check if the working directory exists export function checkDirectoryExist(cwd: string): typeof logger | undefined { if (!fs.lstatSync(cwd).isDirectory()) { - return logger.error(`The working directory ${cwd} does not exist.`) + return logger.error({ + args: [`The working directory ${cwd} does not exist.`] + }) } } diff --git a/packages/cli-t/src/utils/get-package-manager/get-package-manager.ts b/packages/cli-t/src/utils/get-package-manager/get-package-manager.ts new file mode 100644 index 0000000..f8d8f31 --- /dev/null +++ b/packages/cli-t/src/utils/get-package-manager/get-package-manager.ts @@ -0,0 +1,27 @@ +import { Agent, detect } from '@antfu/ni' + +export async function get_package_manager( + cwd: string +): Promise> { + const packageManager = await detect({ + programmatic: true, + cwd + }) + + if (packageManager === 'yarn@berry') return 'yarn' + if (packageManager === 'pnpm@6') return 'pnpm' + if (!packageManager) return 'npm' + + return packageManager +} + +export async function getPackageRunner( + cwd: string, + pm: Exclude +): Promise<'pnpm dlx' | 'bunx' | 'npx'> { + const packageManager = pm ?? (await get_package_manager(cwd)) + + if (packageManager === 'pnpm') return 'pnpm dlx' + if (packageManager === 'bun') return 'bunx' + return 'npx' +} diff --git a/packages/cli-t/src/utils/get-package-manager/index.ts b/packages/cli-t/src/utils/get-package-manager/index.ts new file mode 100644 index 0000000..b59e884 --- /dev/null +++ b/packages/cli-t/src/utils/get-package-manager/index.ts @@ -0,0 +1 @@ +export * from './get-package-manager' diff --git a/packages/cli-t/src/utils/get-project-config/get-project-config.dto.ts b/packages/cli-t/src/utils/get-project-config/get-project-config.dto.ts index 3a3d39d..43c845b 100644 --- a/packages/cli-t/src/utils/get-project-config/get-project-config.dto.ts +++ b/packages/cli-t/src/utils/get-project-config/get-project-config.dto.ts @@ -35,5 +35,3 @@ export const config_cchema = raw_config_schema.extend({ ui: z.string() }) }) - -export type ConfigType = z.infer diff --git a/packages/cli-t/src/utils/get-project-config/get-project-config.ts b/packages/cli-t/src/utils/get-project-config/get-project-config.ts index 65f8b37..71b57b8 100644 --- a/packages/cli-t/src/utils/get-project-config/get-project-config.ts +++ b/packages/cli-t/src/utils/get-project-config/get-project-config.ts @@ -1,5 +1,4 @@ import { loadConfig } from 'tsconfig-paths' -import { logger } from '../logger' import { explorer } from './get-project-config.constants' import { resolve_import } from '../resolve-import' import { @@ -13,6 +12,7 @@ import { get_ts_config_alias_prefix } from '../get-project-info' import { checkTypeScriptInstalled } from '../checkers' +import { logger } from '../text-styling' import { get_project_type } from '../get-project-type' export async function get_raw_config( @@ -26,7 +26,9 @@ export async function get_raw_config( return raw_config_schema.parse(rawConfig.config) } catch (error) { - logger.error(`Invalid configuration found in ${cwd}/components.json.`) + logger.error({ + args: [`Invalid configuration found in ${cwd}/components.json.`] + }) process.exit(1) } } @@ -46,9 +48,11 @@ export async function resolve_config_paths(cwd: string, config: RawConfigType) { const ts_config = loadConfig(cwd) if (ts_config.resultType === 'failed') { - return logger.error( - `Failed to leaod ${config.tsx ? 'tsconfig' : 'jsconfig'}.json. ${ts_config.message ?? ''}`.trim() - ) + return logger.error({ + args: [ + `Failed to leaod ${config.tsx ? 'tsconfig' : 'jsconfig'}.json. ${ts_config.message ?? ''}`.trim() + ] + }) } return config_cchema.parse({ diff --git a/packages/cli-t/src/utils/get-project-info/get-project-info.constants.ts b/packages/cli-t/src/utils/get-project-info/get-project-info.constants.ts index 770cab1..f1b6010 100644 --- a/packages/cli-t/src/utils/get-project-info/get-project-info.constants.ts +++ b/packages/cli-t/src/utils/get-project-info/get-project-info.constants.ts @@ -9,5 +9,5 @@ export const IGNORED_DIRECTORIES = [ ] export const tailwindCssInstallationGuide = { - info: 'please install TailwindCss: https://github.com/tailwindlabs/tailwindcss' + info: 'You need to install TailwindCss:' } diff --git a/packages/cli-t/src/utils/get-project-info/get-project-info.ts b/packages/cli-t/src/utils/get-project-info/get-project-info.ts old mode 100644 new mode 100755 index 7117735..ff4f4bb --- a/packages/cli-t/src/utils/get-project-info/get-project-info.ts +++ b/packages/cli-t/src/utils/get-project-info/get-project-info.ts @@ -4,6 +4,7 @@ import { IGNORED_DIRECTORIES } from './get-project-info.constants' import path from 'path' import { loadConfig } from 'tsconfig-paths' import { type PackageJson } from 'type-fest' +import { logger } from '../text-styling' // Get TailwindCss File export async function get_tailwindcss_file(cwd: string) { @@ -50,8 +51,23 @@ export async function get_ts_config_alias_prefix(cwd: string) { } // Get package.json -export function getPackageJson(): PackageJson { - const packageJsonPath = path.join('package.json') +export function getPackageJson(): PackageJson | null { + const files = fg.sync(['package.json'], { + cwd: process.cwd(), + deep: 1, + ignore: IGNORED_DIRECTORIES + }) + + if (!files.length) { + logger.error({ args: ['package.json not found'] }) + return process.exit(1) + } + + const packageJsonPath = path.join(process.cwd(), 'package.json') + + const packageJson: PackageJson = JSON.parse( + fs.readFileSync(packageJsonPath, 'utf8') + ) - return JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')) + return packageJson } diff --git a/packages/cli-t/src/utils/get-project-type/get-project-type.constants.ts b/packages/cli-t/src/utils/get-project-type/get-project-type.constants.ts new file mode 100644 index 0000000..e6be4af --- /dev/null +++ b/packages/cli-t/src/utils/get-project-type/get-project-type.constants.ts @@ -0,0 +1,11 @@ +import { detectNextJs } from './get-project-type.lib' + +export enum ProjectTypeEnum { + NEXT_JS = 'Next.js', + VITE = 'Vite', + CREATE_REACT_APP = 'Create React App', + UNKNOWN = 'Unknown' +} + +// Gather all detectors in a single array +export const detectors = [detectNextJs] diff --git a/packages/cli-t/src/utils/get-project-type/get-project-type.dto.ts b/packages/cli-t/src/utils/get-project-type/get-project-type.dto.ts new file mode 100644 index 0000000..877ca1a --- /dev/null +++ b/packages/cli-t/src/utils/get-project-type/get-project-type.dto.ts @@ -0,0 +1,11 @@ +import { z } from 'zod' +import { enumToArray } from '../transformers' +import { ProjectTypeEnum } from './get-project-type.constants' + +export const project_types = enumToArray(ProjectTypeEnum) + +export const project_types_schema = z.enum([ + ...(project_types as [string, ...string[]]) +]) + +export type ProjectType = ProjectTypeEnum diff --git a/packages/cli-t/src/utils/get-project-type/get-project-type.lib.ts b/packages/cli-t/src/utils/get-project-type/get-project-type.lib.ts new file mode 100644 index 0000000..33e6043 --- /dev/null +++ b/packages/cli-t/src/utils/get-project-type/get-project-type.lib.ts @@ -0,0 +1,20 @@ +import fg from 'fast-glob' +import { Detector } from './get-project-type.types' +import { IGNORED_DIRECTORIES } from '../get-project-info' + +// Detect NextJs +export const detectNextJs: Detector = { + type: 'NEXT_JS', + detect: async (cwd: string) => { + const files = await fg.glob('**/*', { + cwd, + deep: 3, + ignore: IGNORED_DIRECTORIES + }) + + const is_nextjs = files.find((file) => file.includes('next.config')) + + if (is_nextjs) return true + return false + } +} diff --git a/packages/cli-t/src/utils/get-project-type/get-project-type.ts b/packages/cli-t/src/utils/get-project-type/get-project-type.ts index c643ed0..b61cc7e 100644 --- a/packages/cli-t/src/utils/get-project-type/get-project-type.ts +++ b/packages/cli-t/src/utils/get-project-type/get-project-type.ts @@ -1,27 +1,12 @@ -import fs from 'fs-extra' -import fg from 'fast-glob' -import { IGNORED_DIRECTORIES } from '../get-project-info' -import path from 'path' -export async function get_project_type(cwd: string) { - const files = await fg.glob('**/*', { - cwd, - deep: 3, - ignore: IGNORED_DIRECTORIES - }) - - const is_nextjs = files.find((file) => file.includes('next.config.js')) - if (is_nextjs) { - return 'nextjs' +import { detectors, ProjectTypeEnum } from './get-project-type.constants' +import { ProjectType } from './get-project-type.types' + +export async function get_project_type(cwd: string): Promise { + for (const detector of detectors) { + const isDetected = await detector.detect(cwd) + if (isDetected) { + return detector.type + } } - - const is_using_src_dir = await fs.pathExists(path.resolve(cwd, 'src')) - const is_using_app_dir = await fs.pathExists( - path.resolve(cwd, `${is_using_src_dir ? 'src/' : ''}app`) - ) - - if (is_using_app_dir) { - return is_using_src_dir ? 'next-app-src' : 'nextjs-app' - } - - return is_using_src_dir ? 'next-pages-src' : 'next-pages' + return 'UNKNOWN' } diff --git a/packages/cli-t/src/utils/get-project-type/get-project-type.types.ts b/packages/cli-t/src/utils/get-project-type/get-project-type.types.ts new file mode 100644 index 0000000..aaf9a2a --- /dev/null +++ b/packages/cli-t/src/utils/get-project-type/get-project-type.types.ts @@ -0,0 +1,8 @@ +import { ProjectTypeEnum } from './get-project-type.constants' + +export interface Detector { + type: keyof typeof ProjectTypeEnum + detect: (cwd: string) => Promise +} + +export type ProjectType = keyof typeof ProjectTypeEnum diff --git a/packages/cli-t/src/utils/get-project-type/index.ts b/packages/cli-t/src/utils/get-project-type/index.ts index 42e9a2c..614ef86 100644 --- a/packages/cli-t/src/utils/get-project-type/index.ts +++ b/packages/cli-t/src/utils/get-project-type/index.ts @@ -1 +1,5 @@ export * from './get-project-type' +export * from './get-project-type.lib' +export * from './get-project-type.types' +export * from './get-project-type.dto' +export * from './get-project-type.constants' diff --git a/packages/cli-t/src/utils/index.ts b/packages/cli-t/src/utils/index.ts index f65b666..8d2437c 100644 --- a/packages/cli-t/src/utils/index.ts +++ b/packages/cli-t/src/utils/index.ts @@ -4,3 +4,7 @@ export * from './get-project-info' export * from './get-project-config' export * from './get-project-type' export * from './text-styling' +export * from './url-mutating' +export * from './pref-light-tailwindcss' +export * from './transformers' +export * from './get-package-manager' diff --git a/packages/cli-t/src/utils/pref-light-tailwindcss/index.ts b/packages/cli-t/src/utils/pref-light-tailwindcss/index.ts new file mode 100644 index 0000000..14072d7 --- /dev/null +++ b/packages/cli-t/src/utils/pref-light-tailwindcss/index.ts @@ -0,0 +1,3 @@ +export * from './pref-light-tailwindcss' +export * from './pref-light-tailwindcss.dto' +export * from './pref-light-tailwindcss.constants' diff --git a/packages/cli-t/src/utils/pref-light-tailwindcss/pref-light-tailwindcss.constants.ts b/packages/cli-t/src/utils/pref-light-tailwindcss/pref-light-tailwindcss.constants.ts new file mode 100644 index 0000000..0a132c8 --- /dev/null +++ b/packages/cli-t/src/utils/pref-light-tailwindcss/pref-light-tailwindcss.constants.ts @@ -0,0 +1,34 @@ +import { PromptObject } from 'prompts' +import { highlighter } from '../text-styling' + +export const tailwindcss_prompts: PromptObject[] = [ + { + type: 'confirm', + name: 'tailwind', + message: `Would you like to use ${highlighter.info('TailwindCSS')}`, + initial: false, + active: 'yes', + inactive: 'no' + } +] + +//NOTE: willing to support more when we have more frameworks to support with duck-ui +export const tailwindcss_dependencies = [ + 'tailwindcss', + 'postcss', + 'autoprefixer' +] + +export const tailwindcss_init = ['tailwindcss', 'init', '-p'] + +export const default_config = `/** @type {import('tailwindcss').Config} */ + export default { + content: [ + "./index.html", + "./src/**/*.{js,ts,jsx,tsx}", + ], + theme: { + extend: {}, + }, + plugins: [], + };` diff --git a/packages/cli-t/src/utils/pref-light-tailwindcss/pref-light-tailwindcss.dto.ts b/packages/cli-t/src/utils/pref-light-tailwindcss/pref-light-tailwindcss.dto.ts new file mode 100644 index 0000000..b381988 --- /dev/null +++ b/packages/cli-t/src/utils/pref-light-tailwindcss/pref-light-tailwindcss.dto.ts @@ -0,0 +1,10 @@ +import { z } from 'zod' + +export const pref_light_options_schema = z.object({ + tailwind: z + .boolean({ + message: 'You have to pick one option', + description: 'Would you like to use TailwindCSS? (yes/no) -default: no' + }) + .default(false) +}) diff --git a/packages/cli-t/src/utils/pref-light-tailwindcss/pref-light-tailwindcss.lib.ts b/packages/cli-t/src/utils/pref-light-tailwindcss/pref-light-tailwindcss.lib.ts new file mode 100644 index 0000000..f6e4bdb --- /dev/null +++ b/packages/cli-t/src/utils/pref-light-tailwindcss/pref-light-tailwindcss.lib.ts @@ -0,0 +1,73 @@ +import { execa } from 'execa' +import path from 'path' +import { get_package_manager, getPackageRunner } from '../get-package-manager' +import { spinner } from '../spinner' +import { highlighter, logger } from '../text-styling' +import { + default_config, + tailwindcss_dependencies, + tailwindcss_init +} from './pref-light-tailwindcss.constants' +import fs from 'fs-extra' +import { ProjectType } from '../get-project-type' + +export async function install_tailwindcss( + cwd: string, + type: ProjectType, + typescript: boolean +) { + const install_spinner = spinner( + highlighter.info('Installing TailwindCSS...') + ).start() + + const packageManager = await get_package_manager(cwd) + const { failed: installation_step_1 } = await execa( + packageManager, + [packageManager !== 'npm' ? 'install' : 'add', ...tailwindcss_dependencies], + { + cwd: cwd, + shell: true + } + ) + if (installation_step_1) return install_spinner.fail() + + const packageRunner = await getPackageRunner(cwd, packageManager) + const { failed: installation_step_2 } = await execa( + packageRunner, + [...tailwindcss_init], + { + cwd: cwd, + shell: true + } + ) + if (installation_step_2) return install_spinner.fail() + + // Replacing default config with tailwind config that matches the project type + await adding_tailwind_config(cwd, type, typescript) + + logger.break() + install_spinner.succeed() +} + +export async function adding_tailwind_config( + cwd: string, + type: ProjectType, + typescript: boolean +) { + const tailwind_config_spinner = spinner( + highlighter.info('Adding TailwindCSS config...') + ).start() + + await fs.writeFile( + path.join(cwd, `tailwind.config.${typescript ? 'ts' : 'js'}`), + tailwind_config(type) + ) + + logger.break() + tailwind_config_spinner.succeed() +} + +// NOTE: you have to support other types of projects +export const tailwind_config = (type: ProjectType) => { + return type === 'UNKNOWN' ? default_config : default_config +} diff --git a/packages/cli-t/src/utils/pref-light-tailwindcss/pref-light-tailwindcss.ts b/packages/cli-t/src/utils/pref-light-tailwindcss/pref-light-tailwindcss.ts new file mode 100644 index 0000000..e2b3b38 --- /dev/null +++ b/packages/cli-t/src/utils/pref-light-tailwindcss/pref-light-tailwindcss.ts @@ -0,0 +1,28 @@ +import { checkTailwindCssInstalled } from '../checkers' +import prompts from 'prompts' +import { tailwindcss_prompts } from './pref-light-tailwindcss.constants' +import { pref_light_options_schema } from './pref-light-tailwindcss.dto' +import { get_project_type } from '../get-project-type' +import { spinner } from '../spinner' +import { highlighter, logger } from '../text-styling' +import { tailwindCssInstallationGuide } from '../get-project-info' +import { install_tailwindcss } from './pref-light-tailwindcss.lib' + +export async function pref_light_tailwindcss( + cwd: string, + typescript: boolean +): Promise { + const is_tailwind_installed = await checkTailwindCssInstalled(cwd) + + if (is_tailwind_installed) return + + logger.info({ args: [tailwindCssInstallationGuide] }) + + const options = await prompts(tailwindcss_prompts) + const { tailwind } = pref_light_options_schema.parse(options) + + if (!tailwind) return + + const type = await get_project_type(cwd) + await install_tailwindcss(cwd, type, typescript) +} diff --git a/packages/cli-t/src/utils/spinner.ts b/packages/cli-t/src/utils/spinner.ts index 96affb0..333556b 100644 --- a/packages/cli-t/src/utils/spinner.ts +++ b/packages/cli-t/src/utils/spinner.ts @@ -7,6 +7,7 @@ export function spinner( } ) { return ora({ + color: 'yellow', text, isSilent: options?.silent }) diff --git a/packages/cli-t/src/utils/text-styling/index.ts b/packages/cli-t/src/utils/text-styling/index.ts index a1f264a..6a1a282 100644 --- a/packages/cli-t/src/utils/text-styling/index.ts +++ b/packages/cli-t/src/utils/text-styling/index.ts @@ -1,2 +1,3 @@ export * from './logger' export * from './highlighter' +export * from './text-styling.types' diff --git a/packages/cli-t/src/utils/text-styling/logger.ts b/packages/cli-t/src/utils/text-styling/logger.ts index 2338f3c..ff2ee77 100644 --- a/packages/cli-t/src/utils/text-styling/logger.ts +++ b/packages/cli-t/src/utils/text-styling/logger.ts @@ -1,38 +1,44 @@ import kleur from 'kleur' import logSymbols from 'log-symbols' +import { LoggerParams, LoggerType } from './text-styling.types' const { error, warning, info, success } = logSymbols -export const logger = { - error(...args: unknown[]) { +// Define the logger object with proper types +export const logger: LoggerType = { + error: ({ with_icon = true, args }: LoggerParams): LoggerType => { console.log( - kleur.red([error, 'ERROR:'].join(' ')), + kleur.red([with_icon ? error : '', 'ERROR:'].join(' ')), kleur.red(args.join(' ')) ) - return this + return logger }, - warn(...args: unknown[]) { + + warn: ({ with_icon = true, args }: LoggerParams): LoggerType => { console.log( - kleur.yellow([warning, 'WARN:'].join(' ')), + kleur.yellow([with_icon ? warning : '', 'WARN:'].join(' ')), kleur.yellow(args.join(' ')) ) - return this + return logger }, - info(...args: unknown[]) { + + info: ({ with_icon = true, args }: LoggerParams): LoggerType => { console.log( - kleur.green([info, 'INFO:'].join(' ')), + kleur.green([with_icon ? info : '', 'INFO:'].join(' ')), kleur.green(args.join(' ')) ) - return this + return logger }, - success(...args: unknown[]) { + + success: ({ args, with_icon }: LoggerParams): LoggerType => { console.log( - kleur.green([success, 'SUCCESS:'].join(' ')), + kleur.green([with_icon ? success : '', 'SUCCESS:'].join(' ')), kleur.green(args.join(' ')) ) - return this + return logger }, - break() { + + break: (): LoggerType => { console.log('') - return this + return logger } } diff --git a/packages/cli-t/src/utils/text-styling/text-styling.types.ts b/packages/cli-t/src/utils/text-styling/text-styling.types.ts new file mode 100644 index 0000000..97b5104 --- /dev/null +++ b/packages/cli-t/src/utils/text-styling/text-styling.types.ts @@ -0,0 +1,12 @@ +export interface LoggerParams { + with_icon?: boolean + args: unknown[] +} + +export type LoggerType = { + error: ({ with_icon, args }: LoggerParams) => any + warn: ({ with_icon, args }: LoggerParams) => any + info: ({ with_icon, args }: LoggerParams) => any + success: ({ with_icon, args }: LoggerParams) => any + break: () => any +} diff --git a/packages/cli-t/src/utils/transformers/index.ts b/packages/cli-t/src/utils/transformers/index.ts new file mode 100644 index 0000000..a907164 --- /dev/null +++ b/packages/cli-t/src/utils/transformers/index.ts @@ -0,0 +1 @@ +export * from './transformers' diff --git a/packages/cli-t/src/utils/transformers/transformers.ts b/packages/cli-t/src/utils/transformers/transformers.ts new file mode 100644 index 0000000..d2e2e9e --- /dev/null +++ b/packages/cli-t/src/utils/transformers/transformers.ts @@ -0,0 +1,3 @@ +export function enumToArray(enumObj: T): T[keyof T][] { + return Object.values(enumObj) as T[keyof T][] +} diff --git a/packages/cli-t/test/package.json b/packages/cli-t/test/package.json new file mode 100644 index 0000000..3d17568 --- /dev/null +++ b/packages/cli-t/test/package.json @@ -0,0 +1,17 @@ +{ + "name": "test", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "autoprefixer": "^10.4.20", + "postcss": "^8.4.41", + "tailwindcss": "^3.4.10" + } +} diff --git a/packages/cli-t/test/postcss.config.js b/packages/cli-t/test/postcss.config.js new file mode 100644 index 0000000..33ad091 --- /dev/null +++ b/packages/cli-t/test/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} diff --git a/packages/cli-t/test/tailwind.config.js b/packages/cli-t/test/tailwind.config.js new file mode 100644 index 0000000..6065e03 --- /dev/null +++ b/packages/cli-t/test/tailwind.config.js @@ -0,0 +1,11 @@ +/** @type {import('tailwindcss').Config} */ + export default { + content: [ + "./index.html", + "./src/**/*.{js,ts,jsx,tsx}", + ], + theme: { + extend: {}, + }, + plugins: [], + }; \ No newline at end of file diff --git a/packages/cli-t/tsup.config.ts b/packages/cli-t/tsup.config.ts new file mode 100644 index 0000000..2ad772f --- /dev/null +++ b/packages/cli-t/tsup.config.ts @@ -0,0 +1,12 @@ +import { defineConfig } from 'tsup' + +export default defineConfig({ + clean: true, + dts: true, + entry: ['src/index.ts'], + format: ['esm'], + sourcemap: true, + minify: true, + target: 'esnext', + outDir: 'dist' +}) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 282d49c..7ca3484 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -610,7 +610,7 @@ importers: specifier: ^4.1.2 version: 4.1.2 - packages/cli: + packages/cli-old: dependencies: '@antfu/ni': specifier: ^0.21.4 @@ -704,70 +704,49 @@ importers: specifier: ^4.9.3 version: 4.9.5 - packages/cli-old: + packages/cli-t: dependencies: '@antfu/ni': - specifier: ^0.21.4 + specifier: ^0.21.12 version: 0.21.12 - '@babel/core': - specifier: ^7.22.1 - version: 7.25.8 - '@babel/parser': - specifier: ^7.22.6 - version: 7.25.8 - '@babel/plugin-transform-typescript': - specifier: ^7.22.5 - version: 7.25.7(@babel/core@7.25.8) chalk: specifier: 5.2.0 version: 5.2.0 commander: - specifier: ^10.0.0 + specifier: ^10.0.1 version: 10.0.1 cosmiconfig: - specifier: ^8.1.3 + specifier: ^8.3.6 version: 8.3.6(typescript@4.9.5) - diff: - specifier: ^5.1.0 - version: 5.2.0 - dotenv: - specifier: ^16.4.5 - version: 16.4.5 execa: - specifier: ^7.0.0 - version: 7.2.0 + specifier: ^9.4.1 + version: 9.4.1 fast-glob: specifier: ^3.3.2 version: 3.3.2 fs-extra: - specifier: ^11.1.0 + specifier: ^11.2.0 version: 11.2.0 - https-proxy-agent: - specifier: ^6.2.0 - version: 6.2.1 - lodash.template: - specifier: ^4.5.0 - version: 4.5.0 - node-fetch: - specifier: ^3.3.0 - version: 3.3.2 + globals: + specifier: ^15.11.0 + version: 15.11.0 + kleur: + specifier: ^4.1.5 + version: 4.1.5 + log-symbols: + specifier: ^7.0.0 + version: 7.0.0 ora: - specifier: ^6.1.2 + specifier: ^6.3.1 version: 6.3.1 prompts: specifier: ^2.4.2 version: 2.4.2 - recast: - specifier: ^0.23.2 - version: 0.23.9 - ts-morph: - specifier: ^18.0.0 - version: 18.0.0 tsconfig-paths: specifier: ^4.2.0 version: 4.2.0 zod: - specifier: ^3.20.2 + specifier: ^3.23.8 version: 3.23.8 devDependencies: '@types/babel__core': @@ -798,50 +777,17 @@ importers: specifier: ^4.9.3 version: 4.9.5 - packages/cli-t: + packages/cli-t/test: dependencies: - '@types/fs-extra': - specifier: ^11.0.1 - version: 11.0.4 - '@types/node': - specifier: ^17.0.45 - version: 17.0.45 - chalk: - specifier: 5.2.0 - version: 5.2.0 - commander: - specifier: ^10.0.0 - version: 10.0.1 - cosmiconfig: - specifier: ^8.1.3 - version: 8.3.6(typescript@5.6.3) - fast-glob: - specifier: ^3.3.2 - version: 3.3.2 - fs-extra: - specifier: ^11.1.0 - version: 11.2.0 - globals: - specifier: ^15.9.0 - version: 15.11.0 - kleur: - specifier: ^4.1.5 - version: 4.1.5 - log-symbols: - specifier: ^7.0.0 - version: 7.0.0 - ora: - specifier: ^6.1.2 - version: 6.3.1 - tsconfig-paths: - specifier: ^4.2.0 - version: 4.2.0 - type-fest: - specifier: ^3.8.0 - version: 3.13.1 - zod: - specifier: ^3.23.8 - version: 3.23.8 + autoprefixer: + specifier: ^10.4.20 + version: 10.4.20(postcss@8.4.47) + postcss: + specifier: ^8.4.41 + version: 8.4.47 + tailwindcss: + specifier: ^3.4.10 + version: 3.4.14(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)) packages: @@ -880,6 +826,10 @@ packages: resolution: {integrity: sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==} engines: {node: '>=6.9.0'} + '@babel/code-frame@7.25.9': + resolution: {integrity: sha512-z88xeGxnzehn2sqZ8UdGQEvYErF1odv2CftxInpSYJt6uHuPe9YjahKZITGs3l5LeI9d2ROG+obuDAoSlqbNfQ==} + engines: {node: '>=6.9.0'} + '@babel/compat-data@7.25.8': resolution: {integrity: sha512-ZsysZyXY4Tlx+Q53XdnOFmqwfB9QDTHYxaZYajWRoBLuLEAwI2UIbtxOjWh/cFaa9IKUlcB+DDuoskLuKu56JA==} engines: {node: '>=6.9.0'} @@ -950,6 +900,10 @@ packages: resolution: {integrity: sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@7.25.9': + resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} + engines: {node: '>=6.9.0'} + '@babel/helper-validator-option@7.25.7': resolution: {integrity: sha512-ytbPLsm+GjArDYXJ8Ydr1c/KJuutjF2besPNbIZnZ6MKUxi/uTA22t2ymmA4WFjZFpjiAMO0xuuJPqK2nvDVfQ==} engines: {node: '>=6.9.0'} @@ -962,6 +916,10 @@ packages: resolution: {integrity: sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==} engines: {node: '>=6.9.0'} + '@babel/highlight@7.25.9': + resolution: {integrity: sha512-llL88JShoCsth8fF8R4SJnIn+WLvR6ccFxu1H3FlMhDontdcmZWf2HgIZ7AIqV3Xcck1idlohrN4EUBQz6klbw==} + engines: {node: '>=6.9.0'} + '@babel/parser@7.25.8': resolution: {integrity: sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ==} engines: {node: '>=6.0.0'} @@ -4241,6 +4199,11 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true + browserslist@4.24.2: + resolution: {integrity: sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} @@ -4805,6 +4768,9 @@ packages: electron-to-chromium@1.5.41: resolution: {integrity: sha512-dfdv/2xNjX0P8Vzme4cfzHqnPm5xsZXwsolTYr0eyW18IUmNyG08vL+fttvinTfhKfIKdRoqkDIC9e9iWQCNYQ==} + electron-to-chromium@1.5.45: + resolution: {integrity: sha512-vOzZS6uZwhhbkZbcRyiy99Wg+pYFV5hk+5YaECvx0+Z31NR3Tt5zS6dze2OepT6PCTzVzT0dIJItti+uAW5zmw==} + embla-carousel-autoplay@8.0.0-rc15: resolution: {integrity: sha512-ABTbDJGNb9jzI9OV2vSpbUvxUA0ELmK0SI3yPm8Haj3ghssS+vElfahoDqp7zuFkWBRih6w3B51oMPKdF5J55A==} peerDependencies: @@ -8000,11 +7966,11 @@ packages: tippy.js@6.3.7: resolution: {integrity: sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==} - tldts-core@6.1.52: - resolution: {integrity: sha512-j4OxQI5rc1Ve/4m/9o2WhWSC4jGc4uVbCINdOEJRAraCi0YqTqgMcxUx7DbmuP0G3PCixoof/RZB0Q5Kh9tagw==} + tldts-core@6.1.55: + resolution: {integrity: sha512-BL+BuKHHaOpntE5BGI6naXjULU6aRlgaYdfDHR3T/hdbNTWkWUZ9yuc11wGnwgpvRwlyUiIK+QohYK3olaVU6Q==} - tldts@6.1.52: - resolution: {integrity: sha512-fgrDJXDjbAverY6XnIt0lNfv8A0cf7maTEaZxNykLGsLG7XP+5xhjBTrt/ieAsFjAlZ+G5nmXomLcZDkxXnDzw==} + tldts@6.1.55: + resolution: {integrity: sha512-HxQR/9roQ07Pwc8RyyrJMAxRz5/ssoF3qIPPUiIo3zUt6yMdmYZjM2OZIFMiZ3jHyz9jrGHEHuQZrUhoc1LkDw==} hasBin: true tmp@0.0.33: @@ -8844,6 +8810,11 @@ snapshots: '@babel/highlight': 7.25.7 picocolors: 1.1.1 + '@babel/code-frame@7.25.9': + dependencies: + '@babel/highlight': 7.25.9 + picocolors: 1.1.1 + '@babel/compat-data@7.25.8': {} '@babel/core@7.25.8': @@ -8955,6 +8926,8 @@ snapshots: '@babel/helper-validator-identifier@7.25.7': {} + '@babel/helper-validator-identifier@7.25.9': {} + '@babel/helper-validator-option@7.25.7': {} '@babel/helpers@7.25.7': @@ -8969,6 +8942,13 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 + '@babel/highlight@7.25.9': + dependencies: + '@babel/helper-validator-identifier': 7.25.9 + chalk: 2.4.2 + js-tokens: 4.0.0 + picocolors: 1.1.1 + '@babel/parser@7.25.8': dependencies: '@babel/types': 7.25.8 @@ -9014,7 +8994,7 @@ snapshots: '@babel/types@7.25.8': dependencies: '@babel/helper-string-parser': 7.25.7 - '@babel/helper-validator-identifier': 7.25.7 + '@babel/helper-validator-identifier': 7.25.9 to-fast-properties: 2.0.0 '@changesets/apply-release-plan@7.0.5': @@ -11688,7 +11668,7 @@ snapshots: '@types/fs-extra@11.0.4': dependencies: '@types/jsonfile': 6.1.4 - '@types/node': 17.0.45 + '@types/node': 20.5.1 '@types/hast@2.3.10': dependencies: @@ -11709,7 +11689,7 @@ snapshots: '@types/jsonfile@6.1.4': dependencies: - '@types/node': 17.0.45 + '@types/node': 20.5.1 '@types/keyv@3.1.4': dependencies: @@ -11758,7 +11738,7 @@ snapshots: '@types/prompts@2.4.9': dependencies: - '@types/node': 17.0.45 + '@types/node': 20.5.1 kleur: 3.0.3 '@types/prop-types@15.7.13': {} @@ -12230,7 +12210,7 @@ snapshots: autoprefixer@10.4.20(postcss@8.4.47): dependencies: - browserslist: 4.24.0 + browserslist: 4.24.2 caniuse-lite: 1.0.30001669 fraction.js: 4.3.7 normalize-range: 0.1.2 @@ -12319,6 +12299,13 @@ snapshots: node-releases: 2.0.18 update-browserslist-db: 1.1.1(browserslist@4.24.0) + browserslist@4.24.2: + dependencies: + caniuse-lite: 1.0.30001669 + electron-to-chromium: 1.5.45 + node-releases: 2.0.18 + update-browserslist-db: 1.1.1(browserslist@4.24.2) + buffer-from@1.1.2: {} buffer@5.7.1: @@ -12890,6 +12877,8 @@ snapshots: electron-to-chromium@1.5.41: {} + electron-to-chromium@1.5.45: {} + embla-carousel-autoplay@8.0.0-rc15(embla-carousel@8.0.0-rc15): dependencies: embla-carousel: 8.0.0-rc15 @@ -15594,7 +15583,7 @@ snapshots: parse-json@5.2.0: dependencies: - '@babel/code-frame': 7.25.7 + '@babel/code-frame': 7.25.9 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -15680,6 +15669,14 @@ snapshots: ts-node: 10.9.2(@types/node@20.5.1)(typescript@4.9.5) postcss-load-config@4.0.2(postcss@8.4.47)(ts-node@10.9.2(@types/node@17.0.45)(typescript@5.6.3)): + dependencies: + lilconfig: 3.1.2 + yaml: 2.6.0 + optionalDependencies: + postcss: 8.4.47 + ts-node: 10.9.2(@types/node@17.0.45)(typescript@5.6.3) + + postcss-load-config@4.0.2(postcss@8.4.47)(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)): dependencies: lilconfig: 3.1.2 yaml: 2.6.0 @@ -16913,6 +16910,33 @@ snapshots: transitivePeerDependencies: - ts-node + tailwindcss@3.4.14(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)): + dependencies: + '@alloc/quick-lru': 5.2.0 + arg: 5.0.2 + chokidar: 3.6.0 + didyoumean: 1.2.2 + dlv: 1.1.3 + fast-glob: 3.3.2 + glob-parent: 6.0.2 + is-glob: 4.0.3 + jiti: 1.21.6 + lilconfig: 2.1.0 + micromatch: 4.0.8 + normalize-path: 3.0.0 + object-hash: 3.0.0 + picocolors: 1.1.1 + postcss: 8.4.47 + postcss-import: 15.1.0(postcss@8.4.47) + postcss-js: 4.0.1(postcss@8.4.47) + postcss-load-config: 4.0.2(postcss@8.4.47)(ts-node@10.9.2(@types/node@20.5.1)(typescript@5.6.3)) + postcss-nested: 6.2.0(postcss@8.4.47) + postcss-selector-parser: 6.1.2 + resolve: 1.22.8 + sucrase: 3.35.0 + transitivePeerDependencies: + - ts-node + tapable@2.2.1: {} tar-fs@2.1.1: @@ -17007,11 +17031,11 @@ snapshots: dependencies: '@popperjs/core': 2.11.8 - tldts-core@6.1.52: {} + tldts-core@6.1.55: {} - tldts@6.1.52: + tldts@6.1.55: dependencies: - tldts-core: 6.1.52 + tldts-core: 6.1.55 tmp@0.0.33: dependencies: @@ -17038,7 +17062,7 @@ snapshots: tough-cookie@5.0.0: dependencies: - tldts: 6.1.52 + tldts: 6.1.55 tr46@0.0.3: {} @@ -17084,6 +17108,25 @@ snapshots: '@ts-morph/common': 0.23.0 code-block-writer: 13.0.3 + ts-node@10.9.2(@types/node@17.0.45)(typescript@5.6.3): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.11 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 17.0.45 + acorn: 8.13.0 + acorn-walk: 8.3.4 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.6.3 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + optional: true + ts-node@10.9.2(@types/node@20.5.1)(typescript@4.9.5): dependencies: '@cspotcode/source-map-support': 0.8.1 @@ -17434,6 +17477,12 @@ snapshots: escalade: 3.2.0 picocolors: 1.1.1 + update-browserslist-db@1.1.1(browserslist@4.24.2): + dependencies: + browserslist: 4.24.2 + escalade: 3.2.0 + picocolors: 1.1.1 + uri-js@4.4.1: dependencies: punycode: 2.3.1 @@ -17680,7 +17729,7 @@ snapshots: '@webassemblyjs/wasm-parser': 1.12.1 acorn: 8.13.0 acorn-import-attributes: 1.9.5(acorn@8.13.0) - browserslist: 4.24.0 + browserslist: 4.24.2 chrome-trace-event: 1.0.4 enhanced-resolve: 5.17.1 es-module-lexer: 1.5.4