From f082db5ceec542e4dedc1550a142187529333c7e Mon Sep 17 00:00:00 2001 From: Vaibhavi <55849924+vaibhk20@users.noreply.github.com> Date: Fri, 13 Sep 2024 15:38:27 +0530 Subject: [PATCH 01/71] Create init-gluestack-ui-expo-app.yml --- .../workflows/init-gluestack-ui-expo-app.yml | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 .github/workflows/init-gluestack-ui-expo-app.yml diff --git a/.github/workflows/init-gluestack-ui-expo-app.yml b/.github/workflows/init-gluestack-ui-expo-app.yml new file mode 100644 index 00000000..7781787a --- /dev/null +++ b/.github/workflows/init-gluestack-ui-expo-app.yml @@ -0,0 +1,78 @@ +name: Initialize Gluestack-UI in Expo App + +on: + push: + branches: + - patch + pull_request: + branches: + - patch + +jobs: + test: + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + package-manager: [npm, yarn, pnpm, bun] + runs-on: ${{ matrix.os }} + env: + working-directory: packages/gluestack-cli + steps: + - uses: actions/checkout@v3 + + - name: Use Node.js v18.x + uses: actions/setup-node@v3 + with: + node-version: "18.x" + + - name: Install package manager + run: | + if [ "${{ matrix.package-manager }}" == "yarn" ]; then + npm install -g yarn + elif [ "${{ matrix.package-manager }}" == "pnpm" ]; then + npm install -g pnpm + elif [ "${{ matrix.package-manager }}" == "bun" ]; then + curl -fsSL https://bun.sh/install | bash + fi + + - name: Install dependencies + working-directory: ${{ env.working-directory }} + run: ${{ matrix.package-manager }} install + + - name: Build project + working-directory: ${{ env.working-directory }} + run: ${{ matrix.package-manager }} run build + + - name: Create Expo app + run: | + npx create-expo-app test-expo-app + cd test-expo-app + echo "EXPO_PROJECT_DIR=$PWD" >> $GITHUB_ENV + + - name: Run Gluestack-UI CLI command + working-directory: ${{ env.EXPO_PROJECT_DIR }} + run: | + if [ "${{ runner.os }}" == "Windows" ]; then + npx.cmd gluestack-ui init + else + npx gluestack-ui init + fi + + - name: Install Expo CLI + run: ${{ matrix.package-manager }} add -g expo-cli + + - name: Start Expo app + working-directory: ${{ env.EXPO_PROJECT_DIR }} + run: | + timeout 2m expo start & + sleep 120 + if [ $? -eq 124 ]; then + echo "Expo app started successfully" + else + echo "Failed to start Expo app" + exit 1 + fi + + - name: Run tests + working-directory: ${{ env.working-directory }} + run: ${{ matrix.package-manager }} test From 3bbf5ef44d98d5995bde742e416985f5447ed4de Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Fri, 13 Sep 2024 16:46:55 +0530 Subject: [PATCH 02/71] workflow update --- .github/workflows/init-gluestack-ui-expo-app.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/init-gluestack-ui-expo-app.yml b/.github/workflows/init-gluestack-ui-expo-app.yml index 7781787a..00da5ee0 100644 --- a/.github/workflows/init-gluestack-ui-expo-app.yml +++ b/.github/workflows/init-gluestack-ui-expo-app.yml @@ -37,7 +37,16 @@ jobs: - name: Install dependencies working-directory: ${{ env.working-directory }} - run: ${{ matrix.package-manager }} install + run: | + if [ "${{ matrix.package-manager }}" == "npm" ]; then + npm install --legacy-peer-deps + elif [ "${{ matrix.package-manager }}" == "yarn" ]; then + yarn install --ignore-engines + elif [ "${{ matrix.package-manager }}" == "pnpm" ]; then + pnpm install --no-strict-peer-dependencies + elif [ "${{ matrix.package-manager }}" == "bun" ]; then + bun install + fi - name: Build project working-directory: ${{ env.working-directory }} From 7d57d5c17db355ca05543d98235f95102c2df327 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Fri, 13 Sep 2024 17:33:45 +0530 Subject: [PATCH 03/71] workflow testing --- .../workflows/init-gluestack-ui-expo-app.yml | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/.github/workflows/init-gluestack-ui-expo-app.yml b/.github/workflows/init-gluestack-ui-expo-app.yml index 00da5ee0..8f949478 100644 --- a/.github/workflows/init-gluestack-ui-expo-app.yml +++ b/.github/workflows/init-gluestack-ui-expo-app.yml @@ -35,22 +35,12 @@ jobs: curl -fsSL https://bun.sh/install | bash fi - - name: Install dependencies + - name: Install dependencies (prevent updates to lock file) working-directory: ${{ env.working-directory }} - run: | - if [ "${{ matrix.package-manager }}" == "npm" ]; then - npm install --legacy-peer-deps - elif [ "${{ matrix.package-manager }}" == "yarn" ]; then - yarn install --ignore-engines - elif [ "${{ matrix.package-manager }}" == "pnpm" ]; then - pnpm install --no-strict-peer-dependencies - elif [ "${{ matrix.package-manager }}" == "bun" ]; then - bun install - fi - - - name: Build project + run: yarn + - name: Building working-directory: ${{ env.working-directory }} - run: ${{ matrix.package-manager }} run build + run: yarn build - name: Create Expo app run: | From 1ebc6d1f3bb5f9cb2658692b54e7b44cae3ba92b Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Thu, 26 Sep 2024 16:14:06 +0530 Subject: [PATCH 04/71] feat: added new flags in init --- packages/gluestack-cli/src/commands/init.ts | 19 +++++++++++++++++-- packages/gluestack-cli/src/util/index.ts | 8 ++++++-- packages/gluestack-cli/src/util/init/index.ts | 7 ++++++- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/packages/gluestack-cli/src/commands/init.ts b/packages/gluestack-cli/src/commands/init.ts index ece88021..d22fd114 100644 --- a/packages/gluestack-cli/src/commands/init.ts +++ b/packages/gluestack-cli/src/commands/init.ts @@ -13,6 +13,8 @@ const initOptionsSchema = z.object({ useYarn: z.boolean(), usePnpm: z.boolean(), path: z.string().optional(), + templateOnly: z.boolean(), + projectType: z.string(), }); export const init = new Command() @@ -25,9 +27,20 @@ export const init = new Command() '--path ', 'path to the components directory. defaults to components/ui' ) + .option( + '--template-only templateOnly', + 'Only install the template without installing dependencies', + false + ) + .option( + '--projectType ', + 'Type of project to initialize', + 'library' + ) .action(async (opts) => { try { const options = initOptionsSchema.parse({ ...opts }); + const isTemplate = options.templateOnly; const cwd = process.cwd(); //if cwd doesn't have package.json file if (!fs.existsSync(path.join(cwd, 'package.json'))) { @@ -52,9 +65,11 @@ export const init = new Command() } } // Detect project type - const projectType = await detectProjectType(cwd); + const projectType = isTemplate + ? options.projectType + : await detectProjectType(cwd); // Initialize the gluestack - InitializeGlueStack({ projectType }); + InitializeGlueStack({ projectType, isTemplate }); } catch (err) { handleError(err); } diff --git a/packages/gluestack-cli/src/util/index.ts b/packages/gluestack-cli/src/util/index.ts index b447cac6..98acc345 100644 --- a/packages/gluestack-cli/src/util/index.ts +++ b/packages/gluestack-cli/src/util/index.ts @@ -457,10 +457,14 @@ async function getAdditionalDependencies( style: string ) { try { - let additionalDependencies = { + let additionalDependencies: { + dependencies: {}; + devDependencies?: {}; + } = { dependencies: {}, - devDependencies: {} || undefined, + devDependencies: {}, }; + if (style === config.nativeWindRootPath) { if (projectType && projectType !== 'library') { additionalDependencies.dependencies = diff --git a/packages/gluestack-cli/src/util/init/index.ts b/packages/gluestack-cli/src/util/init/index.ts index 276833ac..fb70b957 100644 --- a/packages/gluestack-cli/src/util/init/index.ts +++ b/packages/gluestack-cli/src/util/init/index.ts @@ -35,8 +35,10 @@ interface TSConfig { const InitializeGlueStack = async ({ projectType = 'library', + isTemplate = false, }: { projectType: string; + isTemplate?: boolean; }) => { try { const initializeStatus = await checkIfInitialized(_currDir); @@ -46,7 +48,10 @@ const InitializeGlueStack = async ({ ); process.exit(1); } - const confirmOverride = await overrideWarning(filesToOverride(projectType)); + const confirmOverride = isTemplate + ? true + : await overrideWarning(filesToOverride(projectType)); + console.log(`\n\x1b[1mInitializing gluestack-ui v2...\x1b[0m\n`); await cloneRepositoryAtRoot(join(_homeDir, config.gluestackDir)); const inputComponent = [config.providerComponent]; From e54a4cdfa1312b3a054b978ca91195cda37fb9ac Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Thu, 26 Sep 2024 16:35:15 +0530 Subject: [PATCH 05/71] feat: added package manager flags --- packages/gluestack-cli/src/commands/add.ts | 22 +++++++- packages/gluestack-cli/src/commands/init.ts | 22 +++++++- packages/gluestack-cli/src/config.ts | 1 + packages/gluestack-cli/src/util/index.ts | 61 ++++++++++++++------- 4 files changed, 85 insertions(+), 21 deletions(-) diff --git a/packages/gluestack-cli/src/commands/add.ts b/packages/gluestack-cli/src/commands/add.ts index 0fffe9a2..e9f2f314 100644 --- a/packages/gluestack-cli/src/commands/add.ts +++ b/packages/gluestack-cli/src/commands/add.ts @@ -4,7 +4,12 @@ import { handleError } from '../util/handle-error'; import { log } from '@clack/prompts'; import { componentAdder, hookAdder, isHookFromConfig } from '../util/add'; import { config } from '../config'; -import { checkWritablePath, isValidPath, projectRootPath } from '../util'; +import { + checkWritablePath, + getPackageMangerFlag, + isValidPath, + projectRootPath, +} from '../util'; import { checkIfInitialized, getComponentsPath } from '../util/config'; const addOptionsSchema = z.object({ @@ -13,6 +18,7 @@ const addOptionsSchema = z.object({ useNpm: z.boolean(), useYarn: z.boolean(), usePnpm: z.boolean(), + useBun: z.boolean(), path: z.string().optional(), }); @@ -24,6 +30,7 @@ export const add = new Command() .option('--use-npm ,useNpm', 'use npm to install dependencies', false) .option('--use-yarn, useYarn', 'use yarn to install dependencies', false) .option('--use-pnpm, usePnpm', 'use pnpm to install dependencies', false) + .option('--use-bun, useBun', 'use bun to install dependencies', false) .option('--path ', 'path to the components directory') .action(async (components, opts, command) => { try { @@ -53,6 +60,19 @@ export const add = new Command() ); process.exit(1); } + //if multiple package managers are used + if ( + (options.useNpm && options.useYarn) || + (options.useNpm && options.usePnpm) || + (options.useYarn && options.usePnpm) + ) { + log.error( + `\x1b[31mMultiple package managers selected. Please select only one package manager.\x1b[0m` + ); + process.exit(1); + } + //define package manager + getPackageMangerFlag(options); //function to get current path where GUIProvider is located const currWritablePath = await getComponentsPath(projectRootPath); if (currWritablePath) { diff --git a/packages/gluestack-cli/src/commands/init.ts b/packages/gluestack-cli/src/commands/init.ts index d22fd114..0778b68b 100644 --- a/packages/gluestack-cli/src/commands/init.ts +++ b/packages/gluestack-cli/src/commands/init.ts @@ -4,7 +4,12 @@ import { handleError } from '../util/handle-error'; import { log } from '@clack/prompts'; import { InitializeGlueStack } from '../util/init'; import { config } from '../config'; -import { checkWritablePath, detectProjectType, isValidPath } from '../util'; +import { + checkWritablePath, + detectProjectType, + getPackageMangerFlag, + isValidPath, +} from '../util'; import path, { resolve } from 'path'; import fs from 'fs'; @@ -12,6 +17,7 @@ const initOptionsSchema = z.object({ useNpm: z.boolean(), useYarn: z.boolean(), usePnpm: z.boolean(), + useBun: z.boolean(), path: z.string().optional(), templateOnly: z.boolean(), projectType: z.string(), @@ -23,6 +29,7 @@ export const init = new Command() .option('--use-npm ,useNpm', 'use npm to install dependencies', false) .option('--use-yarn, useYarn', 'use yarn to install dependencies', false) .option('--use-pnpm, usePnpm', 'use pnpm to install dependencies', false) + .option('--use-bun, useBun', 'use bun to install dependencies', false) .option( '--path ', 'path to the components directory. defaults to components/ui' @@ -49,6 +56,19 @@ export const init = new Command() ); process.exit(1); } + //if multiple package managers are used + if ( + (options.useNpm && options.useYarn) || + (options.useNpm && options.usePnpm) || + (options.useYarn && options.usePnpm) + ) { + log.error( + `\x1b[31mMultiple package managers selected. Please select only one package manager.\x1b[0m` + ); + process.exit(1); + } + //define package manager + getPackageMangerFlag(options); //if path option is used if (options.path) { // Check if the string starts with "/" or "." diff --git a/packages/gluestack-cli/src/config.ts b/packages/gluestack-cli/src/config.ts index d2dc14ce..80a21640 100644 --- a/packages/gluestack-cli/src/config.ts +++ b/packages/gluestack-cli/src/config.ts @@ -20,6 +20,7 @@ const config = { gluestackUIPattern: '@gluestack-ui/', templatesDir: '../../../template', codeModesDir: '../../../template/codemods', + packageManager: null as string | null, }; export { config }; diff --git a/packages/gluestack-cli/src/util/index.ts b/packages/gluestack-cli/src/util/index.ts index 98acc345..3fd0bc2b 100644 --- a/packages/gluestack-cli/src/util/index.ts +++ b/packages/gluestack-cli/src/util/index.ts @@ -133,21 +133,21 @@ const wait = (msec: number): Promise => }); //checking from root -const detectLockFile = (): string | null => { - const packageLockPath = join(projectRootPath, 'package-lock.json'); - const yarnLockPath = join(projectRootPath, 'yarn.lock'); - const pnpmLockPath = join(projectRootPath, 'pnpm-lock.yaml'); - - if (fs.existsSync(packageLockPath)) { - return 'npm'; - } else if (fs.existsSync(yarnLockPath)) { - return 'yarn'; - } else if (fs.existsSync(pnpmLockPath)) { - return 'pnpm'; - } else { - return null; - } -}; +// const detectLockFile = (): string | null => { +// const packageLockPath = join(projectRootPath, 'package-lock.json'); +// const yarnLockPath = join(projectRootPath, 'yarn.lock'); +// const pnpmLockPath = join(projectRootPath, 'pnpm-lock.yaml'); + +// if (fs.existsSync(packageLockPath)) { +// return 'npm'; +// } else if (fs.existsSync(yarnLockPath)) { +// return 'yarn'; +// } else if (fs.existsSync(pnpmLockPath)) { +// return 'pnpm'; +// } else { +// return null; +// } +// }; //checking from cwd function findLockFileType(): string | null { @@ -175,6 +175,25 @@ function findLockFileType(): string | null { } } +function getPackageMangerFlag(options: any) { + if (options.useBun) { + config.packageManager = 'bun'; + return 'bun'; + } + if (options.usePnpm) { + config.packageManager = 'pnpm'; + return 'pnpm'; + } + if (options.useYarn) { + config.packageManager = 'yarn'; + return 'yarn'; + } + if (options.useNpm) { + config.packageManager = 'npm'; + return 'npm'; + } +} + const promptVersionManager = async (): Promise => { const packageManager = await select({ message: @@ -200,10 +219,13 @@ const installDependencies = async ( try { //add npmrc file for legacy-peer-deps-support execSync('npm config --location=project set legacy-peer-deps=true'); - let versionManager: string | null = findLockFileType(); - if (!versionManager) { - versionManager = await promptVersionManager(); - } + let versionManager: string | null; + if (!config.packageManager) { + versionManager = findLockFileType(); + if (!versionManager) { + versionManager = await promptVersionManager(); + } + } else versionManager = config.packageManager; const dependenciesToInstall: { dependencies: Dependency; devDependencies: Dependency; @@ -576,4 +598,5 @@ export { removeHyphen, getRelativePath, ensureFilesPromise, + getPackageMangerFlag, }; From 9caa77d1d0165cc5d028da89406492d6fc66f3b0 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Fri, 27 Sep 2024 15:48:08 +0530 Subject: [PATCH 06/71] v0.7.10-alpha.0.1 --- packages/gluestack-cli/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gluestack-cli/package.json b/packages/gluestack-cli/package.json index f7f2bb7f..47a567a8 100644 --- a/packages/gluestack-cli/package.json +++ b/packages/gluestack-cli/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for easily adding components from gluestack to your projects.", - "version": "0.7.10", + "version": "0.7.10-alpha.0.1", "license": "MIT", "main": "dist/index.js", "files": [ From e7ce6b38a687b6ac906e7d200927b1fb88b627f3 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Fri, 27 Sep 2024 15:49:25 +0530 Subject: [PATCH 07/71] feat: updated create gluestack flow --- packages/gluestack/junit.xml | 28 +------- packages/gluestack/package.json | 2 +- packages/gluestack/src/v2.ts | 114 +++++++++++++++++++++++--------- 3 files changed, 88 insertions(+), 56 deletions(-) diff --git a/packages/gluestack/junit.xml b/packages/gluestack/junit.xml index e5dcaee2..dc54a1fb 100644 --- a/packages/gluestack/junit.xml +++ b/packages/gluestack/junit.xml @@ -1,29 +1,7 @@ - - - - - - - - - - - - Error: thrown: "Exceeded timeout of 50000 ms for a test. -Add a timeout value to this test to increase the timeout, if this is a long-running test. See https://jestjs.io/docs/api#testname-fn-timeout." - at it (/Users/virajajayjoshi/WorkSpace/gluestack-ui-cli/packages/create-next-app-with-gluestack-ui/__tests__/integration/next-app-router.test.js:35:3) - at _dispatchDescribe (/Users/virajajayjoshi/WorkSpace/gluestack-ui-cli/node_modules/jest-circus/build/index.js:91:26) - at describe (/Users/virajajayjoshi/WorkSpace/gluestack-ui-cli/node_modules/jest-circus/build/index.js:55:5) - at Object.describe (/Users/virajajayjoshi/WorkSpace/gluestack-ui-cli/packages/create-next-app-with-gluestack-ui/__tests__/integration/next-app-router.test.js:22:1) - at Runtime._execModule (/Users/virajajayjoshi/WorkSpace/gluestack-ui-cli/node_modules/jest-runtime/build/index.js:1430:24) - at Runtime._loadModule (/Users/virajajayjoshi/WorkSpace/gluestack-ui-cli/node_modules/jest-runtime/build/index.js:1013:12) - at Runtime.requireModule (/Users/virajajayjoshi/WorkSpace/gluestack-ui-cli/node_modules/jest-runtime/build/index.js:873:12) - at jestAdapter (/Users/virajajayjoshi/WorkSpace/gluestack-ui-cli/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:77:13) - at processTicksAndRejections (node:internal/process/task_queues:95:5) - at runTestInternal (/Users/virajajayjoshi/WorkSpace/gluestack-ui-cli/node_modules/jest-runner/build/runTest.js:367:16) - at runTest (/Users/virajajayjoshi/WorkSpace/gluestack-ui-cli/node_modules/jest-runner/build/runTest.js:444:34) - at Object.worker (/Users/virajajayjoshi/WorkSpace/gluestack-ui-cli/node_modules/jest-runner/build/testWorker.js:106:12) + + + \ No newline at end of file diff --git a/packages/gluestack/package.json b/packages/gluestack/package.json index 2fe9dd3a..27cc2eb4 100644 --- a/packages/gluestack/package.json +++ b/packages/gluestack/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for working with gluestack", - "version": "2.0.1", + "version": "2.0.1-alpha.0.1", "license": "MIT", "main": "./dist/index.js", "bin": "./dist/index.js", diff --git a/packages/gluestack/src/v2.ts b/packages/gluestack/src/v2.ts index fb43db5c..f4bfec80 100644 --- a/packages/gluestack/src/v2.ts +++ b/packages/gluestack/src/v2.ts @@ -7,15 +7,65 @@ import { displayHelp } from './help'; import templatesMap from './data.js'; const { gitRepo, tag, options } = templatesMap; -export async function main(args: string[]) { - const supportedFrameworkArgs = [ - '--expo', - '--expo-router', - '--next-app-router', - '--next-page-router', - '--react-native', - ]; +type RouterType = 'legacy' | 'latest'; +type PackageManager = 'npm' | 'yarn' | 'pnpm' | 'bun'; + +interface ProjectOptions { + projectType: string; + router: RouterType; + packageManager?: PackageManager; + projectName: string; +} + +async function createProject(createOptions: ProjectOptions) { + const { projectName, projectType, packageManager, router } = createOptions; + let createCommand = ''; + console.log(`Creating project: ${projectName}`); + if (projectType.includes('expo')) { + // create expo project + + createCommand = router.includes('expo-router') + ? `npx create-expo-app@latest ${projectName} --template expo-template-blank-typescript --use-${packageManager}` + : `npx create-expo-app@latest ${projectName} --template typescript --use-${packageManager}`; + } else if (projectType.includes('next')) { + // create next project + + createCommand = projectType.includes('next-page-router') + ? `npx create-next-app@latest ${projectName} --ts --use-${packageManager}` + : `npx create-next-app@latest ${projectName} --ts --use-${packageManager}`; + } else if (projectType.includes('react-native')) { + // create react-native project + + createCommand = `npx @react-native-community/cli@latest init ${projectName} --use-${packageManager}`; + } + try { + execSync(createCommand, { stdio: 'inherit' }); + console.log(`Successfully created project: ${projectName}`); + } catch (e) { + console.error(`Failed to create project: ${e}`); + throw e; + } +} + +async function initializeGluestack(projectOptions: ProjectOptions) { + const { projectName, packageManager, projectType } = projectOptions; + try { + execSync(`cd ${projectName}`, { stdio: 'inherit' }); + execSync( + `npx gluestack-ui@alpha init --template-only --projectType ${projectType} --use-${packageManager}`, + { stdio: 'inherit' } + ); + execSync(`npx gluestack-ui@alpha add --all --use-${packageManager}`, { + stdio: 'inherit', + }); + } catch (e) { + console.log('Failed to initialize gluestack-ui'); + throw e; + } +} + +export async function main(args: string[]) { console.log(chalk.bold.magenta('\nWelcome to gluestack-ui v2!')); console.log(chalk.yellow('Creating a new project with gluestack-ui v2.')); console.log( @@ -26,26 +76,20 @@ export async function main(args: string[]) { ) ); + const supportedFrameworkArgs = [ + '--expo', + '--expo-router', + '--next-app-router', + '--next-page-router', + '--react-native', + ]; const supportedStyleArgs = ['--gs', '--nw']; - const supportedPackagemanagers = ['npm', 'yarn', 'pnpm', 'bun']; + const supportedDocumentationArgs = ['--help', '-h']; const supportedPackagemanagerArgs = supportedPackagemanagers.map( (manager) => '--use-' + manager ); - const supportedDocumentationArgs = ['--help', '-h']; - - // let supportedArgs = [ - // // frameworks - // ...supportedFrameworkArgs, - // // style options - // ...supportedStyleArgs, - // // package manager - // ...supportedPackagemanagerArgs, - // // documentation - // ...supportedDocumentationArgs, - // ]; - let selectedFramework = ''; let selectedRouter = ''; let selectedStyle = ''; @@ -134,14 +178,24 @@ export async function main(args: string[]) { selectedPackageManager = 'npm'; } } - - const templateDir = templatesMap.map[templateName]; - - // @ts-ignore - await cloneProject(projName, templateDir); - - await installDependencies(projName, selectedPackageManager); - console.log('done ...'); + const createOptions: ProjectOptions = { + projectType: selectedFramework, + router: selectedRouter as RouterType, + packageManager: selectedPackageManager as PackageManager, + projectName: projName, + }; + console.log('createOptions--->', createOptions); + try { + // @ts-ignore + // await cloneProject(projName, templateDir); + // await installDependencies(projName, selectedPackageManager); + // await createProject(createOptions); + // await initializeGluestack(createOptions); + console.log('done ...'); + } catch { + console.log('Failed to create project'); + process.exit(1); + } } async function cloneProject(projectName: string, templateName: string) { From 1143ea57a1db674045c0d862a7ca3d04f5138014 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Fri, 27 Sep 2024 16:50:58 +0530 Subject: [PATCH 08/71] v2.0.1-alpha.0.2 --- packages/gluestack/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gluestack/package.json b/packages/gluestack/package.json index 27cc2eb4..3a78672e 100644 --- a/packages/gluestack/package.json +++ b/packages/gluestack/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for working with gluestack", - "version": "2.0.1-alpha.0.1", + "version": "2.0.1-alpha.0.2", "license": "MIT", "main": "./dist/index.js", "bin": "./dist/index.js", From ab3746a74c4615fcc05d59c2959e9d8abf20d3d3 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Fri, 27 Sep 2024 18:52:17 +0530 Subject: [PATCH 09/71] v2.0.1-alpha.0.3 --- packages/gluestack/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/gluestack/package.json b/packages/gluestack/package.json index 3a78672e..8d8d3d6d 100644 --- a/packages/gluestack/package.json +++ b/packages/gluestack/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for working with gluestack", - "version": "2.0.1-alpha.0.2", + "version": "2.0.1-alpha.0.3", "license": "MIT", "main": "./dist/index.js", "bin": "./dist/index.js", @@ -42,7 +42,7 @@ "@clack/prompts": "^0.6.3", "@gluestack/cli-utils": "0.1.11", "@types/minimist": "^1.2.2", - "chalk": "^5.3.0", + "chalk": "4.1.2", "find-package-json": "^1.2.0", "fs-extra": "^11.1.1", "simple-git": "^3.16.0" From b31ee8649da18cba803cc94915862c6da3c8810a Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Mon, 30 Sep 2024 11:17:47 +0530 Subject: [PATCH 10/71] feat: project types defined --- packages/gluestack/src/data.js | 8 ++++++-- packages/gluestack/src/v2.ts | 6 +++--- packages/gluestack/yarn.lock | 21 ++++++++------------- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/packages/gluestack/src/data.js b/packages/gluestack/src/data.js index 7737add8..6b352727 100644 --- a/packages/gluestack/src/data.js +++ b/packages/gluestack/src/data.js @@ -8,9 +8,13 @@ module.exports = { question: 'What would you like to \x1b[36mbuild\x1b[0m?', options: [ { value: 'expo', label: 'Expo app', hint: 'Expo + gluestack-ui' }, - { value: 'next', label: 'Next.js app', hint: 'Next + gluestack-ui' }, { - value: 'react-native', + value: 'nextjs', + label: 'Next.js app', + hint: 'Next + gluestack-ui', + }, + { + value: 'react-native-cli', label: 'React Native app', hint: 'React Native + gluestack-ui', }, diff --git a/packages/gluestack/src/v2.ts b/packages/gluestack/src/v2.ts index f4bfec80..b88a0e91 100644 --- a/packages/gluestack/src/v2.ts +++ b/packages/gluestack/src/v2.ts @@ -20,7 +20,7 @@ interface ProjectOptions { async function createProject(createOptions: ProjectOptions) { const { projectName, projectType, packageManager, router } = createOptions; let createCommand = ''; - console.log(`Creating project: ${projectName}`); + console.log(`Creating project: ${chalk.blue(projectName)}`); if (projectType.includes('expo')) { // create expo project @@ -28,7 +28,7 @@ async function createProject(createOptions: ProjectOptions) { createCommand = router.includes('expo-router') ? `npx create-expo-app@latest ${projectName} --template expo-template-blank-typescript --use-${packageManager}` : `npx create-expo-app@latest ${projectName} --template typescript --use-${packageManager}`; - } else if (projectType.includes('next')) { + } else if (projectType.includes('nextjs')) { // create next project createCommand = projectType.includes('next-page-router') @@ -189,7 +189,7 @@ export async function main(args: string[]) { // @ts-ignore // await cloneProject(projName, templateDir); // await installDependencies(projName, selectedPackageManager); - // await createProject(createOptions); + await createProject(createOptions); // await initializeGluestack(createOptions); console.log('done ...'); } catch { diff --git a/packages/gluestack/yarn.lock b/packages/gluestack/yarn.lock index fa9e2e52..72666846 100644 --- a/packages/gluestack/yarn.lock +++ b/packages/gluestack/yarn.lock @@ -884,6 +884,14 @@ caniuse-lite@^1.0.30001503: resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001514.tgz" integrity sha512-ENcIpYBmwAAOm/V2cXgM7rZUrKKaqisZl4ZAI520FIkqGXUxJjmaIssbRW5HVVR5tyV6ygTLIm15aU8LUmQSaQ== +chalk@4.1.2, chalk@^4.0.0: + version "4.1.2" + resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + chalk@^2.0.0: version "2.4.2" resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" @@ -893,19 +901,6 @@ chalk@^2.0.0: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.0.0: - version "4.1.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chalk@^5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.3.0.tgz#67c20a7ebef70e7f3970a01f90fa210cb6860385" - integrity sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w== - char-regex@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz" From 52387bf085563c9738b59dde6b260626742c9bb9 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Mon, 30 Sep 2024 12:14:56 +0530 Subject: [PATCH 11/71] feat: dependent hooks addition --- packages/gluestack-cli/src/dependencies.ts | 43 +++++++++++-- packages/gluestack-cli/src/util/add/index.ts | 65 ++++++++++++-------- packages/gluestack-cli/src/util/index.ts | 37 ++++++++++- 3 files changed, 114 insertions(+), 31 deletions(-) diff --git a/packages/gluestack-cli/src/dependencies.ts b/packages/gluestack-cli/src/dependencies.ts index 06e244bb..a8d03197 100644 --- a/packages/gluestack-cli/src/dependencies.ts +++ b/packages/gluestack-cli/src/dependencies.ts @@ -1,11 +1,15 @@ export interface Dependency { [key: string]: string; } +export interface ComponentConfig { + dependencies: Dependency; + devDependencies?: Dependency; + additionalComponents?: string[]; + hooks?: string[]; +} + export interface Dependencies { - [key: string]: { - dependencies: Dependency; - devDependencies?: Dependency; - }; + [key: string]: ComponentConfig; } const projectBasedDependencies: Dependencies = { @@ -229,6 +233,35 @@ const dependenciesConfig: Dependencies = { view: { dependencies: {} }, 'virtualized-list': { dependencies: {} }, vstack: { dependencies: {} }, + grid: { + dependencies: {}, + hooks: ['useBreakpointValue'], + }, }; -export { dependenciesConfig, projectBasedDependencies }; +// Ignore components that are in development or not in supported list +const IgnoredComponents = ['bottomsheet']; + +const getComponentDependencies = (componentName: string): ComponentConfig => { + const config = dependenciesConfig[componentName]; + if (!config) { + return { + dependencies: {}, + devDependencies: {}, + additionalComponents: [], + hooks: [], + }; + } + return { + dependencies: config.dependencies || {}, + devDependencies: config.devDependencies || {}, + additionalComponents: config.additionalComponents || [], + hooks: config.hooks || [], + }; +}; +export { + dependenciesConfig, + projectBasedDependencies, + IgnoredComponents, + getComponentDependencies, +}; diff --git a/packages/gluestack-cli/src/util/add/index.ts b/packages/gluestack-cli/src/util/add/index.ts index 430051ef..3795b57f 100644 --- a/packages/gluestack-cli/src/util/add/index.ts +++ b/packages/gluestack-cli/src/util/add/index.ts @@ -4,6 +4,7 @@ import { basename, join, parse } from 'path'; import { log, confirm } from '@clack/prompts'; import { config } from '../../config'; import { + checkAdditionalDependencies, cloneRepositoryAtRoot, getAllComponents, installDependencies, @@ -21,6 +22,7 @@ const componentAdder = async ({ try { console.log(`\n\x1b[1mAdding new component...\x1b[0m\n`); await cloneRepositoryAtRoot(join(_homeDir, config.gluestackDir)); + let hooksToAdd: string[] = []; if ( requestedComponent && requestedComponent !== '--all' && @@ -36,6 +38,9 @@ const componentAdder = async ({ ? getAllComponents() : [requestedComponent]; + const { hooks } = checkAdditionalDependencies(requestedComponents); + hooksToAdd = Array.from(hooks); + const updatedComponents = !existingComponentsChecked && showWarning && requestedComponent ? await isComponentInConfig(requestedComponents) @@ -49,6 +54,7 @@ const componentAdder = async ({ ); await writeComponent(component, targetPath); + await hookAdder({ requestedHook: hooksToAdd[0] }); }) ) .then(async () => { @@ -158,7 +164,11 @@ const confirmOverride = async ( return shouldContinue; }; -const hookAdder = async ({ requestedHook }: { requestedHook: string }) => { +const hookAdder = async ({ + requestedHook, +}: { + requestedHook: string | string[]; +}) => { try { console.log(`\n\x1b[1mAdding new hook...\x1b[0m\n`); await cloneRepositoryAtRoot(join(_homeDir, config.gluestackDir)); @@ -192,32 +202,37 @@ const hookFileName = async (hook: string): Promise => { }); return fileName; }; -const writeHook = async (hook: string) => { - const fileName = await hookFileName(hook); - const utilsPath = join( - projectRootPath, - config.writableComponentsPath, - 'utils', - fileName - ); - const sourceFilePath = join( - _homeDir, - config.gluestackDir, - config.hooksResourcePath, - fileName - ); - if (fs.existsSync(utilsPath)) { - const confirm = await confirmHookOverride(hook); - if (confirm === false) { - processTerminate('Installation aborted'); +const writeHook = async (hooks: string | string[]) => { + const hooksArray = Array.isArray(hooks) ? hooks : [hooks]; + for (const hook of hooksArray) { + const fileName = await hookFileName(hook); + const utilsPath = join( + projectRootPath, + config.writableComponentsPath, + 'utils', + fileName + ); + const sourceFilePath = join( + _homeDir, + config.gluestackDir, + config.hooksResourcePath, + fileName + ); + if (fs.existsSync(utilsPath)) { + const shouldOverride = await confirmHookOverride(hook); + if (!shouldOverride) { + processTerminate('Installation aborted'); + } } - } - try { - await fs.ensureFile(utilsPath); - fs.copyFileSync(sourceFilePath, utilsPath); - } catch (error) { - log.error(`\x1b[31mError: ${(error as Error).message}\x1b[0m`); + try { + await fs.ensureFile(utilsPath); + await fs.copy(sourceFilePath, utilsPath); + } catch (error) { + log.error( + `\x1b[31mError adding hook ${hook}: ${(error as Error).message}\x1b[0m` + ); + } } }; diff --git a/packages/gluestack-cli/src/util/index.ts b/packages/gluestack-cli/src/util/index.ts index b447cac6..c0b53eeb 100644 --- a/packages/gluestack-cli/src/util/index.ts +++ b/packages/gluestack-cli/src/util/index.ts @@ -16,7 +16,9 @@ import { import { Dependencies, Dependency, + IgnoredComponents, dependenciesConfig, + getComponentDependencies, projectBasedDependencies, } from '../dependencies'; import { installNativeWind } from './init'; @@ -46,11 +48,43 @@ const getAllComponents = (): string[] => { (file) => !['.tsx', '.ts', '.jsx', '.js', '.json'].includes( extname(file).toLowerCase() - ) && file !== config.providerComponent + ) && + file !== config.providerComponent && + !IgnoredComponents.includes(file) ); return componentList; }; +interface AdditionalDependencies { + components: string[]; + hooks: string[]; +} + +function checkAdditionalDependencies( + components: string[] +): AdditionalDependencies { + const additionalDependencies: AdditionalDependencies = { + components: [], + hooks: [], + }; + + components.forEach((component) => { + const config = getComponentDependencies(component); + + // Add additional components + config.additionalComponents?.forEach((additionalComponent) => { + additionalDependencies.components.push(additionalComponent); + }); + + // Add hooks + config.hooks?.forEach((hook) => { + additionalDependencies.hooks.push(hook); + }); + }); + + return additionalDependencies; +} + const cloneRepositoryAtRoot = async (rootPath: string) => { try { const clonedRepoExists = await checkIfFolderExists(rootPath); @@ -572,4 +606,5 @@ export { removeHyphen, getRelativePath, ensureFilesPromise, + checkAdditionalDependencies, }; From c263bbb6cbb540bb54121d86a492595138985bd5 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Mon, 30 Sep 2024 16:15:52 +0530 Subject: [PATCH 12/71] feat: code refactor --- packages/gluestack-cli/package.json | 2 +- packages/gluestack-cli/src/dependencies.ts | 1 + .../src/util/config/expo-config-helper.ts | 2 +- .../util/config/react-native-config-helper.ts | 2 +- packages/gluestack-cli/src/util/index.ts | 2 - packages/gluestack-cli/src/util/init/index.ts | 86 ++++++++++--------- .../codemods/expo/babel-config-transform.ts | 12 ++- .../babel-config-transform.ts | 28 +++++- packages/gluestack-cli/yarn.lock | 16 ++-- 9 files changed, 95 insertions(+), 56 deletions(-) diff --git a/packages/gluestack-cli/package.json b/packages/gluestack-cli/package.json index f7f2bb7f..18f23177 100644 --- a/packages/gluestack-cli/package.json +++ b/packages/gluestack-cli/package.json @@ -46,7 +46,7 @@ "@antfu/ni": "^0.21.12", "@clack/prompts": "^0.6.3", "@gluestack/ui-project-detector": "^0.1.1", - "chalk": "^5.3.0", + "chalk": "4.1.2", "commander": "^12.0.0", "fast-glob": "^3.3.2", "find-package-json": "^1.2.0", diff --git a/packages/gluestack-cli/src/dependencies.ts b/packages/gluestack-cli/src/dependencies.ts index a8d03197..bbaddeed 100644 --- a/packages/gluestack-cli/src/dependencies.ts +++ b/packages/gluestack-cli/src/dependencies.ts @@ -46,6 +46,7 @@ const dependenciesConfig: Dependencies = { '@gluestack-ui/toast': 'latest', '@gluestack-ui/nativewind-utils': 'latest', 'react-native-svg': '13.4.0', + nativewind: '4.1.10', }, devDependencies: { jscodeshift: '0.15.2', diff --git a/packages/gluestack-cli/src/util/config/expo-config-helper.ts b/packages/gluestack-cli/src/util/config/expo-config-helper.ts index e57d4760..e9fa0a0f 100644 --- a/packages/gluestack-cli/src/util/config/expo-config-helper.ts +++ b/packages/gluestack-cli/src/util/config/expo-config-helper.ts @@ -124,7 +124,7 @@ async function initNatiwindExpoApp( } --cssPath='${cssPath}' --config='${JSON.stringify(resolvedConfig)}'` ); execSync( - `npx jscodeshift -t ${BabeltransformerPath} ${resolvedConfig.config.babelConfig} --isSDK50='${resolvedConfig.app.sdk50}'` + `npx jscodeshift -t ${BabeltransformerPath} ${resolvedConfig.config.babelConfig} --config='${JSON.stringify(resolvedConfig)}'` ); execSync( `npx jscodeshift -t ${addProviderTransformerPath} ${resolvedConfig.app.entry} --cssImportPath='${cssImportPath}' --componentsPath='${config.writableComponentsPath}'` diff --git a/packages/gluestack-cli/src/util/config/react-native-config-helper.ts b/packages/gluestack-cli/src/util/config/react-native-config-helper.ts index d7e7a49a..86218bad 100644 --- a/packages/gluestack-cli/src/util/config/react-native-config-helper.ts +++ b/packages/gluestack-cli/src/util/config/react-native-config-helper.ts @@ -66,7 +66,7 @@ async function initNatiwindRNApp( ); execSync( - `npx jscodeshift -t ${BabelTransformerPath} ${resolvedConfig.config.babelConfig}` + `npx jscodeshift -t ${BabelTransformerPath} ${resolvedConfig.config.babelConfig} --config='${JSON.stringify(resolvedConfig)}'` ); execSync( `npx jscodeshift -t ${metroTransformerPath} ${resolvedConfig.config.metroConfig}` diff --git a/packages/gluestack-cli/src/util/index.ts b/packages/gluestack-cli/src/util/index.ts index c0b53eeb..8d9c5555 100644 --- a/packages/gluestack-cli/src/util/index.ts +++ b/packages/gluestack-cli/src/util/index.ts @@ -21,7 +21,6 @@ import { getComponentDependencies, projectBasedDependencies, } from '../dependencies'; -import { installNativeWind } from './init'; const homeDir = os.homedir(); const currDir = process.cwd(); @@ -319,7 +318,6 @@ const installDependencies = async ( ); try { - await installNativeWind(versionManager); let depResult; let devDepResult; diff --git a/packages/gluestack-cli/src/util/init/index.ts b/packages/gluestack-cli/src/util/init/index.ts index 276833ac..599a49a5 100644 --- a/packages/gluestack-cli/src/util/init/index.ts +++ b/packages/gluestack-cli/src/util/init/index.ts @@ -97,17 +97,7 @@ async function addProvider() { } } -function createDefaultTSConfig() { - return { - compilerOptions: { - paths: { - '@/*': ['./*'], - }, - }, - exclude: ['node_modules'], - }; -} - +//update tailwind.config.js and codemod async function updateTailwindConfig( resolvedConfig: RawConfig, projectType: string @@ -135,47 +125,62 @@ async function updateTailwindConfig( } } -async function updateTSConfig( - projectType: string, - configPath: string -): Promise { +//updateConfig helper, create default tsconfig.json +function createDefaultTSConfig() { + return { + compilerOptions: { + paths: { + '@/*': ['./*'], + }, + }, + exclude: ['node_modules'], + }; +} +// updateConfig helper, read tsconfig.json +async function readTSConfig(configPath: string): Promise { try { - let tsConfig: TSConfig = {}; - try { - tsConfig = JSON.parse(await readFileAsync(configPath, 'utf8')); - } catch { - //write another function if file is empty - tsConfig = createDefaultTSConfig(); - } + return JSON.parse(await readFileAsync(configPath, 'utf8')); + } catch { + return createDefaultTSConfig(); + } +} +// updateConfig helper, update paths in tsconfig.json +function updatePaths( + paths: Record, + key: string, + newValues: string[] +): void { + paths[key] = Array.from(new Set([...(paths[key] || []), ...newValues])); +} +//update tsconfig.json +async function updateTSConfig(projectType: string, config: any): Promise { + try { + const configPath = config.config.tsConfig; + let tsConfig: TSConfig = await readTSConfig(configPath); + let tailwindConfig = config.tailwind.config; + const tailwindConfigFileName = tailwindConfig?.split('/').pop(); + tsConfig.compilerOptions = tsConfig.compilerOptions || {}; + tsConfig.compilerOptions.paths = tsConfig.compilerOptions.paths || {}; // Next.js project specific configuration if (projectType === config.nextJsProject) { tsConfig.compilerOptions.jsxImportSource = 'nativewind'; } - if (!tsConfig.compilerOptions.paths) { - // Case 1: Paths do not exist, add new paths - tsConfig.compilerOptions.paths = { - '@/*': ['./*'], - }; - } else { - // Case 2 & 3: Paths exist, update them without undoing previous values - const paths = tsConfig.compilerOptions.paths['@/*']; - if (!paths.includes('./*')) { - // If './*' is not included, add it - paths.push('./*'); - } - } + updatePaths(tsConfig.compilerOptions.paths, '@/*', ['./*']); + updatePaths(tsConfig.compilerOptions.paths, 'tailwind.config', [ + `./${tailwindConfigFileName}`, + ]); + await writeFileAsync(configPath, JSON.stringify(tsConfig, null, 2), 'utf8'); } catch (err) { log.error( - `\x1b[31mError occured while installing dependencies (${ - err as Error - })\x1b[0m` + `\x1b[31mError occurred while updating tsconfig.json: ${(err as Error).message}\x1b[0m` ); } } +//update global.css async function updateGlobalCss(resolvedConfig: RawConfig): Promise { try { const globalCSSPath = resolvedConfig.tailwind.css; @@ -235,8 +240,7 @@ async function commonInitialization( join(__dirname, `${config.templatesDir}/common/nativewind-env.d.ts`), join(_currDir, 'nativewind-env.d.ts') ); - permission && - (await updateTSConfig(projectType, resolvedConfig.config.tsConfig)); + permission && (await updateTSConfig(projectType, resolvedConfig)); permission && (await updateGlobalCss(resolvedConfig)); await updateTailwindConfig(resolvedConfig, projectType); @@ -387,4 +391,4 @@ ${files return confirmInput; } -export { InitializeGlueStack, commonInitialization, installNativeWind }; +export { InitializeGlueStack, commonInitialization }; diff --git a/packages/gluestack-cli/template/codemods/expo/babel-config-transform.ts b/packages/gluestack-cli/template/codemods/expo/babel-config-transform.ts index 62b2e8fc..e5338ee8 100644 --- a/packages/gluestack-cli/template/codemods/expo/babel-config-transform.ts +++ b/packages/gluestack-cli/template/codemods/expo/babel-config-transform.ts @@ -4,12 +4,15 @@ import { ObjectExpression, Property, } from 'jscodeshift'; +import { ExpoResolvedConfig } from '../../../src/util/config/config-types'; const transform: Transform = (file, api, options): string => { try { const j = api.jscodeshift; const root = j(file.source); - const isSDK50 = options.isSDK50; + const config: ExpoResolvedConfig = options.config; + const isSDK50 = config.app.sdk50; + const tailwindConfig = config.tailwind.config; root.find(j.ReturnStatement).forEach((path) => { const returnObject = path.node.argument as ObjectExpression | null; @@ -73,6 +76,9 @@ const transform: Transform = (file, api, options): string => { } } + // fetch tailwind config filenName from resolved path of tailwind.config.js + const tailwindConfigFileName = tailwindConfig.split('/').pop(); + //plugin code modification const moduleResolverPlugin = j.arrayExpression([ j.stringLiteral('module-resolver'), @@ -85,6 +91,10 @@ const transform: Transform = (file, api, options): string => { j.identifier('alias'), j.objectExpression([ j.objectProperty(j.stringLiteral('@'), j.stringLiteral('./')), + j.objectProperty( + j.stringLiteral('tailwindConfig'), + j.stringLiteral(`./` + tailwindConfigFileName) + ), ]) ), ]), diff --git a/packages/gluestack-cli/template/codemods/react-native-cli/babel-config-transform.ts b/packages/gluestack-cli/template/codemods/react-native-cli/babel-config-transform.ts index 85b819ea..cd52ceb9 100644 --- a/packages/gluestack-cli/template/codemods/react-native-cli/babel-config-transform.ts +++ b/packages/gluestack-cli/template/codemods/react-native-cli/babel-config-transform.ts @@ -1,9 +1,12 @@ import { Transform } from 'jscodeshift'; +import { ReactNativeResolvedConfig } from '../../../src/util/config/config-types'; -const transform: Transform = (file, api) => { +const transform: Transform = (file, api, options) => { try { const j = api.jscodeshift; const root = j(file.source); + const config: ReactNativeResolvedConfig = options.config; + const tailwindConfig = config.tailwind.config; // Find the module.exports assignment const moduleExports = root.find(j.AssignmentExpression, { @@ -97,6 +100,11 @@ const transform: Transform = (file, api) => { j.identifier('alias'), j.objectExpression([ j.property('init', j.stringLiteral('@'), j.stringLiteral('./')), + j.property( + 'init', + j.stringLiteral('tailwind.config'), + j.stringLiteral('./' + tailwindConfig.split('/').pop()) + ), ]) ), ]), @@ -155,6 +163,11 @@ const transform: Transform = (file, api) => { j.identifier('alias'), j.objectExpression([ j.property('init', j.stringLiteral('@'), j.stringLiteral('./')), + j.property( + 'init', + j.stringLiteral('tailwind.config'), + j.stringLiteral('./' + tailwindConfig.split('/').pop()) + ), ]) ); moduleResolverConfig.properties.push(aliasProp); @@ -165,6 +178,19 @@ const transform: Transform = (file, api) => { aliasProp.value.properties.push( j.property('init', j.stringLiteral('@'), j.stringLiteral('./')) ); + } else if ( + aliasProp.value.type === 'ObjectExpression' && + !aliasProp.value.properties.some( + (p) => p.key.value === 'tailwind.config' + ) + ) { + aliasProp.value.properties.push( + j.property( + 'init', + j.stringLiteral('tailwind.config'), + j.stringLiteral('./' + tailwindConfig.split('/').pop()) + ) + ); } } } diff --git a/packages/gluestack-cli/yarn.lock b/packages/gluestack-cli/yarn.lock index 31102c30..d04f7df9 100644 --- a/packages/gluestack-cli/yarn.lock +++ b/packages/gluestack-cli/yarn.lock @@ -3167,6 +3167,14 @@ caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== +chalk@4.1.2, chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -3184,14 +3192,6 @@ chalk@^3.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - chalk@^5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.3.0.tgz#67c20a7ebef70e7f3970a01f90fa210cb6860385" From b3371658e846f5c17cbdda178bf8ff1ccfa1b887 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Mon, 30 Sep 2024 16:48:15 +0530 Subject: [PATCH 13/71] v2.0.1-alpha.0.4 --- packages/gluestack/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gluestack/package.json b/packages/gluestack/package.json index 8d8d3d6d..ed4c2d8c 100644 --- a/packages/gluestack/package.json +++ b/packages/gluestack/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for working with gluestack", - "version": "2.0.1-alpha.0.3", + "version": "2.0.1-alpha.0.4", "license": "MIT", "main": "./dist/index.js", "bin": "./dist/index.js", From 6e4bfb2bc8ad88ae671530fbca5b33d44dd5d531 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Mon, 30 Sep 2024 16:49:20 +0530 Subject: [PATCH 14/71] feat: create project command --- packages/gluestack/src/v2.ts | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/packages/gluestack/src/v2.ts b/packages/gluestack/src/v2.ts index b88a0e91..106b8d74 100644 --- a/packages/gluestack/src/v2.ts +++ b/packages/gluestack/src/v2.ts @@ -25,19 +25,34 @@ async function createProject(createOptions: ProjectOptions) { if (projectType.includes('expo')) { // create expo project - createCommand = router.includes('expo-router') - ? `npx create-expo-app@latest ${projectName} --template expo-template-blank-typescript --use-${packageManager}` - : `npx create-expo-app@latest ${projectName} --template typescript --use-${packageManager}`; + const templateFlag = router.includes('expo-router') + ? `expo-template-blank-typescript` + : `typescript`; + + switch (packageManager) { + case 'npm': + createCommand = `npx create-expo-app@latest ${projectName} --template ${templateFlag}`; + break; + case 'yarn': + createCommand = `yarn create expo-app ${projectName} --template ${templateFlag}`; + break; + case 'pnpm': + createCommand = `pnpm create expo-app ${projectName} --template ${templateFlag}`; + break; + case 'bun': + createCommand = `npx create expo ${projectName} --template ${templateFlag}`; + break; + } } else if (projectType.includes('nextjs')) { // create next project createCommand = projectType.includes('next-page-router') - ? `npx create-next-app@latest ${projectName} --ts --use-${packageManager}` - : `npx create-next-app@latest ${projectName} --ts --use-${packageManager}`; + ? `npx create-next-app@latest ${projectName} --ts --no-eslint --use-${packageManager} --import-alias "@/*" --tailwind --no-src-dir --no-app` + : `npx create-next-app@latest ${projectName} --ts --no-eslint --use-${packageManager} --import-alias "@/*" --tailwind --no-src-dir --app`; } else if (projectType.includes('react-native')) { // create react-native project - createCommand = `npx @react-native-community/cli@latest init ${projectName} --use-${packageManager}`; + createCommand = `npx @react-native-community/cli@latest init ${projectName} --pm ${packageManager}`; } try { execSync(createCommand, { stdio: 'inherit' }); From 6ca96e61e6e2c241cbde8c89065e63e9cf42408e Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Mon, 30 Sep 2024 17:01:17 +0530 Subject: [PATCH 15/71] v2.0.1-alpha.0.5 --- packages/gluestack/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gluestack/package.json b/packages/gluestack/package.json index ed4c2d8c..96306ab4 100644 --- a/packages/gluestack/package.json +++ b/packages/gluestack/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for working with gluestack", - "version": "2.0.1-alpha.0.4", + "version": "2.0.1-alpha.0.5", "license": "MIT", "main": "./dist/index.js", "bin": "./dist/index.js", From 1aa788c64fd0ec7815bdbb3eb64ac4a72aa47394 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Mon, 30 Sep 2024 17:45:10 +0530 Subject: [PATCH 16/71] fix: create project --- packages/gluestack-cli/src/util/add/index.ts | 6 ++++-- packages/gluestack/src/v2.ts | 12 ++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/packages/gluestack-cli/src/util/add/index.ts b/packages/gluestack-cli/src/util/add/index.ts index 430051ef..b37977c9 100644 --- a/packages/gluestack-cli/src/util/add/index.ts +++ b/packages/gluestack-cli/src/util/add/index.ts @@ -38,7 +38,7 @@ const componentAdder = async ({ const updatedComponents = !existingComponentsChecked && showWarning && requestedComponent - ? await isComponentInConfig(requestedComponents) + ? await isComponentInProject(requestedComponents) : requestedComponents; await Promise.all( updatedComponents.map(async (component) => { @@ -65,7 +65,9 @@ const componentAdder = async ({ } }; -const isComponentInConfig = async (components: string[]): Promise => { +const isComponentInProject = async ( + components: string[] +): Promise => { const alreadyExistingComponents: string[] = []; let componentsToAdd: any = []; for (const component of components) { diff --git a/packages/gluestack/src/v2.ts b/packages/gluestack/src/v2.ts index 106b8d74..ef9b4775 100644 --- a/packages/gluestack/src/v2.ts +++ b/packages/gluestack/src/v2.ts @@ -26,8 +26,8 @@ async function createProject(createOptions: ProjectOptions) { // create expo project const templateFlag = router.includes('expo-router') - ? `expo-template-blank-typescript` - : `typescript`; + ? `blank-typescript` + : ``; switch (packageManager) { case 'npm': @@ -40,7 +40,7 @@ async function createProject(createOptions: ProjectOptions) { createCommand = `pnpm create expo-app ${projectName} --template ${templateFlag}`; break; case 'bun': - createCommand = `npx create expo ${projectName} --template ${templateFlag}`; + createCommand = `bun create expo ${projectName} --template ${templateFlag}`; break; } } else if (projectType.includes('nextjs')) { @@ -64,14 +64,14 @@ async function createProject(createOptions: ProjectOptions) { } async function initializeGluestack(projectOptions: ProjectOptions) { - const { projectName, packageManager, projectType } = projectOptions; + const { projectName, projectType } = projectOptions; try { execSync(`cd ${projectName}`, { stdio: 'inherit' }); execSync( - `npx gluestack-ui@alpha init --template-only --projectType ${projectType} --use-${packageManager}`, + `npx gluestack-ui@alpha init --template-only --projectType ${projectType}`, { stdio: 'inherit' } ); - execSync(`npx gluestack-ui@alpha add --all --use-${packageManager}`, { + execSync(`npx gluestack-ui@alpha add --all`, { stdio: 'inherit', }); } catch (e) { From 53d2e72c88bbb203ebeb015b9513680e694c30ea Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Mon, 30 Sep 2024 18:16:45 +0530 Subject: [PATCH 17/71] fix: code review --- packages/gluestack-cli/src/util/add/index.ts | 8 +++----- .../src/util/config/next-config-helper.ts | 2 +- packages/gluestack-cli/src/util/init/index.ts | 6 +++--- .../template/codemods/expo/babel-config-transform.ts | 3 ++- .../react-native-cli/babel-config-transform.ts | 10 +++++++--- 5 files changed, 16 insertions(+), 13 deletions(-) diff --git a/packages/gluestack-cli/src/util/add/index.ts b/packages/gluestack-cli/src/util/add/index.ts index 3795b57f..cda15041 100644 --- a/packages/gluestack-cli/src/util/add/index.ts +++ b/packages/gluestack-cli/src/util/add/index.ts @@ -29,7 +29,7 @@ const componentAdder = async ({ !(await checkIfComponentIsValid(requestedComponent)) ) { log.error( - `\x1b[31mThe ${requestedComponent} does not exist. Kindly choose a valid component name.\x1b[0m ` + `The ${requestedComponent} does not exist. Kindly choose a valid component name.` ); return; } @@ -54,7 +54,7 @@ const componentAdder = async ({ ); await writeComponent(component, targetPath); - await hookAdder({ requestedHook: hooksToAdd[0] }); + await hookAdder({ requestedHook: hooksToAdd }); }) ) .then(async () => { @@ -229,9 +229,7 @@ const writeHook = async (hooks: string | string[]) => { await fs.ensureFile(utilsPath); await fs.copy(sourceFilePath, utilsPath); } catch (error) { - log.error( - `\x1b[31mError adding hook ${hook}: ${(error as Error).message}\x1b[0m` - ); + log.error(`Error adding hook ${hook}: ${(error as Error).message}`); } } }; diff --git a/packages/gluestack-cli/src/util/config/next-config-helper.ts b/packages/gluestack-cli/src/util/config/next-config-helper.ts index 54fda1f6..98bf6107 100644 --- a/packages/gluestack-cli/src/util/config/next-config-helper.ts +++ b/packages/gluestack-cli/src/util/config/next-config-helper.ts @@ -96,7 +96,7 @@ async function initNatiwindNextApp( ) { // if app router add registry file to root const registryContent = await readFile( - join(__dirname, `${config.templatesDir}/common/registry.tsx`), + join(__dirname, `${config.templatesDir}`, 'common', 'registry.tsx'), 'utf8' ); await writeFile(resolvedConfig.app.registry, registryContent, 'utf8'); diff --git a/packages/gluestack-cli/src/util/init/index.ts b/packages/gluestack-cli/src/util/init/index.ts index 599a49a5..8cf1446b 100644 --- a/packages/gluestack-cli/src/util/init/index.ts +++ b/packages/gluestack-cli/src/util/init/index.ts @@ -158,7 +158,7 @@ async function updateTSConfig(projectType: string, config: any): Promise { const configPath = config.config.tsConfig; let tsConfig: TSConfig = await readTSConfig(configPath); let tailwindConfig = config.tailwind.config; - const tailwindConfigFileName = tailwindConfig?.split('/').pop(); + const tailwindConfigFileName = path.basename(tailwindConfig); tsConfig.compilerOptions = tsConfig.compilerOptions || {}; tsConfig.compilerOptions.paths = tsConfig.compilerOptions.paths || {}; @@ -185,7 +185,7 @@ async function updateGlobalCss(resolvedConfig: RawConfig): Promise { try { const globalCSSPath = resolvedConfig.tailwind.css; const globalCSSContent = await fs.readFile( - join(__dirname, config.templatesDir, 'common/global.css'), + join(__dirname, config.templatesDir, 'common', 'global.css'), 'utf8' ); const existingContent = await fs.readFile(globalCSSPath, 'utf8'); @@ -237,7 +237,7 @@ async function commonInitialization( //add nativewind-env.d.ts contents await fs.copy( - join(__dirname, `${config.templatesDir}/common/nativewind-env.d.ts`), + join(__dirname, config.templatesDir, 'common', 'nativewind-env.d.ts'), join(_currDir, 'nativewind-env.d.ts') ); permission && (await updateTSConfig(projectType, resolvedConfig)); diff --git a/packages/gluestack-cli/template/codemods/expo/babel-config-transform.ts b/packages/gluestack-cli/template/codemods/expo/babel-config-transform.ts index e5338ee8..11fb06c7 100644 --- a/packages/gluestack-cli/template/codemods/expo/babel-config-transform.ts +++ b/packages/gluestack-cli/template/codemods/expo/babel-config-transform.ts @@ -77,7 +77,8 @@ const transform: Transform = (file, api, options): string => { } // fetch tailwind config filenName from resolved path of tailwind.config.js - const tailwindConfigFileName = tailwindConfig.split('/').pop(); + const parts = tailwindConfig.split(/[/\\]/); + const tailwindConfigFileName = parts[parts.length - 1]; //plugin code modification const moduleResolverPlugin = j.arrayExpression([ diff --git a/packages/gluestack-cli/template/codemods/react-native-cli/babel-config-transform.ts b/packages/gluestack-cli/template/codemods/react-native-cli/babel-config-transform.ts index cd52ceb9..09af75a0 100644 --- a/packages/gluestack-cli/template/codemods/react-native-cli/babel-config-transform.ts +++ b/packages/gluestack-cli/template/codemods/react-native-cli/babel-config-transform.ts @@ -8,6 +8,10 @@ const transform: Transform = (file, api, options) => { const config: ReactNativeResolvedConfig = options.config; const tailwindConfig = config.tailwind.config; + // fetch tailwind config filenName from resolved path of tailwind.config.js + const parts = tailwindConfig.split(/[/\\]/); + const tailwindConfigFileName = parts[parts.length - 1]; + // Find the module.exports assignment const moduleExports = root.find(j.AssignmentExpression, { left: { @@ -103,7 +107,7 @@ const transform: Transform = (file, api, options) => { j.property( 'init', j.stringLiteral('tailwind.config'), - j.stringLiteral('./' + tailwindConfig.split('/').pop()) + j.stringLiteral('./' + tailwindConfig) ), ]) ), @@ -166,7 +170,7 @@ const transform: Transform = (file, api, options) => { j.property( 'init', j.stringLiteral('tailwind.config'), - j.stringLiteral('./' + tailwindConfig.split('/').pop()) + j.stringLiteral('./' + tailwindConfigFileName) ), ]) ); @@ -188,7 +192,7 @@ const transform: Transform = (file, api, options) => { j.property( 'init', j.stringLiteral('tailwind.config'), - j.stringLiteral('./' + tailwindConfig.split('/').pop()) + j.stringLiteral('./' + tailwindConfigFileName) ) ); } From c081b77e363e87d4ae4dee067e04288078e84143 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Mon, 30 Sep 2024 18:30:38 +0530 Subject: [PATCH 18/71] fix: code review --- packages/gluestack-cli/src/util/config/next-config-helper.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gluestack-cli/src/util/config/next-config-helper.ts b/packages/gluestack-cli/src/util/config/next-config-helper.ts index 98bf6107..feef2ef1 100644 --- a/packages/gluestack-cli/src/util/config/next-config-helper.ts +++ b/packages/gluestack-cli/src/util/config/next-config-helper.ts @@ -96,7 +96,7 @@ async function initNatiwindNextApp( ) { // if app router add registry file to root const registryContent = await readFile( - join(__dirname, `${config.templatesDir}`, 'common', 'registry.tsx'), + join(__dirname, config.templatesDir, 'common', 'registry.tsx'), 'utf8' ); await writeFile(resolvedConfig.app.registry, registryContent, 'utf8'); From 9d79866592c175bd85b101daa34f3d3798c63cc4 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Mon, 30 Sep 2024 18:56:08 +0530 Subject: [PATCH 19/71] fix: code review --- .../src/util/config/expo-config-helper.ts | 4 +- packages/gluestack-cli/src/util/index.ts | 38 +++++++++---------- packages/gluestack-cli/src/util/init/index.ts | 19 ---------- 3 files changed, 22 insertions(+), 39 deletions(-) diff --git a/packages/gluestack-cli/src/util/config/expo-config-helper.ts b/packages/gluestack-cli/src/util/config/expo-config-helper.ts index e9fa0a0f..87b20d6c 100644 --- a/packages/gluestack-cli/src/util/config/expo-config-helper.ts +++ b/packages/gluestack-cli/src/util/config/expo-config-helper.ts @@ -129,7 +129,9 @@ async function initNatiwindExpoApp( execSync( `npx jscodeshift -t ${addProviderTransformerPath} ${resolvedConfig.app.entry} --cssImportPath='${cssImportPath}' --componentsPath='${config.writableComponentsPath}'` ); - execSync('npx expo install babel-plugin-module-resolver'); + execSync('npx expo install babel-plugin-module-resolver', { + stdio: 'inherit', + }); await commonInitialization(config.expoProject, resolvedConfig, permission); } catch (err) { log.error(`\x1b[31mError: ${err as Error}\x1b[0m`); diff --git a/packages/gluestack-cli/src/util/index.ts b/packages/gluestack-cli/src/util/index.ts index eccd3902..92d091c4 100644 --- a/packages/gluestack-cli/src/util/index.ts +++ b/packages/gluestack-cli/src/util/index.ts @@ -165,23 +165,6 @@ const wait = (msec: number): Promise => setTimeout(resolve, msec); }); -//checking from root -// const detectLockFile = (): string | null => { -// const packageLockPath = join(projectRootPath, 'package-lock.json'); -// const yarnLockPath = join(projectRootPath, 'yarn.lock'); -// const pnpmLockPath = join(projectRootPath, 'pnpm-lock.yaml'); - -// if (fs.existsSync(packageLockPath)) { -// return 'npm'; -// } else if (fs.existsSync(yarnLockPath)) { -// return 'yarn'; -// } else if (fs.existsSync(pnpmLockPath)) { -// return 'pnpm'; -// } else { -// return null; -// } -// }; - //checking from cwd function findLockFileType(): string | null { let currentDir = currDir; @@ -245,19 +228,36 @@ const promptVersionManager = async (): Promise => { return packageManager; }; +async function ensureLegacyPeerDeps() { + //add legacy-peer-deps-support + switch (config.packageManager) { + case 'npm': + execSync('npm config --location=project set legacy-peer-deps=true'); + break; + case 'yarn': + execSync('yarn config set legacy-peer-deps true'); + break; + case 'pnpm': + execSync('pnpm config set legacy-peer-deps true'); + break; + case 'bun': + break; + } +} + const installDependencies = async ( input: string[] | string, additionalDependencies?: Dependencies | undefined ): Promise => { try { - //add npmrc file for legacy-peer-deps-support - execSync('npm config --location=project set legacy-peer-deps=true'); + await ensureLegacyPeerDeps(); let versionManager: string | null; if (!config.packageManager) { versionManager = findLockFileType(); if (!versionManager) { versionManager = await promptVersionManager(); } + config.packageManager = versionManager; } else versionManager = config.packageManager; const dependenciesToInstall: { dependencies: Dependency; diff --git a/packages/gluestack-cli/src/util/init/index.ts b/packages/gluestack-cli/src/util/init/index.ts index 0b6ba065..c14b5f89 100644 --- a/packages/gluestack-cli/src/util/init/index.ts +++ b/packages/gluestack-cli/src/util/init/index.ts @@ -305,25 +305,6 @@ async function generateProjectConfigAndInit( return resolvedConfig; } -//package manager based installation for nativewind@4.0.36 using --save-exact flag, has to be refactored later -//temporary solution for patch -const installNativeWind = async (versionManager: string) => { - switch (versionManager) { - case 'npm': - execSync('npm install --save-exact nativewind@4.0.36 '); - break; - case 'yarn': - execSync('yarn add --exact nativewind@4.0.36'); - break; - case 'pnpm': - execSync('pnpm i --save-exact nativewind@4.0.36 '); - break; - case 'bun': - execSync('bun add --exact nativewind@4.0.36'); - break; - } -}; - //files to override in the project directory data const filesToOverride = (projectType: string) => { switch (projectType) { From 817cffa08e52ccdd80be521d61c533744ba71132 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Tue, 1 Oct 2024 12:34:35 +0530 Subject: [PATCH 20/71] v2.0.1-alpha.0.6 --- packages/gluestack/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gluestack/package.json b/packages/gluestack/package.json index 96306ab4..f351ec87 100644 --- a/packages/gluestack/package.json +++ b/packages/gluestack/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for working with gluestack", - "version": "2.0.1-alpha.0.5", + "version": "2.0.1-alpha.0.6", "license": "MIT", "main": "./dist/index.js", "bin": "./dist/index.js", From 39e6d430cc15d237906a50bbfee37a53fbe99e35 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Tue, 1 Oct 2024 12:34:59 +0530 Subject: [PATCH 21/71] v0.7.10-alpha.0.2 --- packages/gluestack-cli/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gluestack-cli/package.json b/packages/gluestack-cli/package.json index 4a5e381e..e9955040 100644 --- a/packages/gluestack-cli/package.json +++ b/packages/gluestack-cli/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for easily adding components from gluestack to your projects.", - "version": "0.7.10-alpha.0.1", + "version": "0.7.10-alpha.0.2", "license": "MIT", "main": "dist/index.js", "files": [ From 5e86a11c0e58fff07e36326cb2a35748a11457b3 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Tue, 1 Oct 2024 12:48:02 +0530 Subject: [PATCH 22/71] v2.0.1-alpha.0.7 --- packages/gluestack/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gluestack/package.json b/packages/gluestack/package.json index f351ec87..5ec82259 100644 --- a/packages/gluestack/package.json +++ b/packages/gluestack/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for working with gluestack", - "version": "2.0.1-alpha.0.6", + "version": "2.0.1-alpha.0.7", "license": "MIT", "main": "./dist/index.js", "bin": "./dist/index.js", From 9c6dfeaf182b63c3911e18465e0dfd02b1c3a2eb Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Tue, 1 Oct 2024 12:57:25 +0530 Subject: [PATCH 23/71] v0.7.10-alpha.0.3 --- packages/gluestack-cli/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gluestack-cli/package.json b/packages/gluestack-cli/package.json index e9955040..9529cebb 100644 --- a/packages/gluestack-cli/package.json +++ b/packages/gluestack-cli/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for easily adding components from gluestack to your projects.", - "version": "0.7.10-alpha.0.2", + "version": "0.7.10-alpha.0.3", "license": "MIT", "main": "dist/index.js", "files": [ From 34f5593275bda353776570026236fa4e853a61f9 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Tue, 1 Oct 2024 13:37:36 +0530 Subject: [PATCH 24/71] v0.7.10-alpha.0.4 --- packages/gluestack-cli/package.json | 2 +- packages/gluestack-cli/src/util/add/index.ts | 3 +- packages/gluestack-cli/src/util/index.ts | 314 ++++++------------ .../codemods/expo/babel-config-transform.ts | 2 +- packages/gluestack/src/v2.ts | 8 +- 5 files changed, 117 insertions(+), 212 deletions(-) diff --git a/packages/gluestack-cli/package.json b/packages/gluestack-cli/package.json index 9529cebb..c575917d 100644 --- a/packages/gluestack-cli/package.json +++ b/packages/gluestack-cli/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for easily adding components from gluestack to your projects.", - "version": "0.7.10-alpha.0.3", + "version": "0.7.10-alpha.0.4", "license": "MIT", "main": "dist/index.js", "files": [ diff --git a/packages/gluestack-cli/src/util/add/index.ts b/packages/gluestack-cli/src/util/add/index.ts index f1a59993..a1b6706a 100644 --- a/packages/gluestack-cli/src/util/add/index.ts +++ b/packages/gluestack-cli/src/util/add/index.ts @@ -54,7 +54,8 @@ const componentAdder = async ({ ); await writeComponent(component, targetPath); - await hookAdder({ requestedHook: hooksToAdd }); + if (hooksToAdd.length > 0) + await hookAdder({ requestedHook: hooksToAdd }); }) ) .then(async () => { diff --git a/packages/gluestack-cli/src/util/index.ts b/packages/gluestack-cli/src/util/index.ts index 92d091c4..1a438990 100644 --- a/packages/gluestack-cli/src/util/index.ts +++ b/packages/gluestack-cli/src/util/index.ts @@ -2,7 +2,7 @@ import os from 'os'; import fs, { stat } from 'fs-extra'; import simpleGit from 'simple-git'; import { config } from '../config'; -import { exec, execSync, spawnSync } from 'child_process'; +import { execSync, spawnSync } from 'child_process'; import finder from 'find-package-json'; import { join, dirname, extname, relative, basename } from 'path'; import { @@ -14,7 +14,7 @@ import { select, } from '@clack/prompts'; import { - Dependencies, + ComponentConfig, Dependency, IgnoredComponents, dependenciesConfig, @@ -167,28 +167,20 @@ const wait = (msec: number): Promise => //checking from cwd function findLockFileType(): string | null { - let currentDir = currDir; - while (true) { - const packageLockPath = join(currentDir, 'package-lock.json'); - const yarnLockPath = join(currentDir, 'yarn.lock'); - const pnpmLockPath = join(currentDir, 'pnpm-lock.yaml'); - const bunLockPath = join(currentDir, 'bun.lockb'); - - if (fs.existsSync(packageLockPath)) { - return 'npm'; - } else if (fs.existsSync(yarnLockPath)) { - return 'yarn'; - } else if (fs.existsSync(pnpmLockPath)) { - return 'pnpm'; - } else if (fs.existsSync(bunLockPath)) { - return 'bun'; - } else if (currentDir === dirname(currentDir)) { - // Reached root directory - return null; - } else { - currentDir = dirname(currentDir); + const lockFiles: { [key: string]: string } = { + 'package-lock.json': 'npm', + 'yarn.lock': 'yarn', + 'pnpm-lock.yaml': 'pnpm', + 'bun.lockb': 'bun', + }; + let dir = currDir; + while (dir !== dirname(dir)) { + for (const [file, manager] of Object.entries(lockFiles)) { + if (fs.existsSync(join(dir, file))) return manager; } + dir = dirname(dir); } + return null; } function getPackageMangerFlag(options: any) { @@ -228,37 +220,29 @@ const promptVersionManager = async (): Promise => { return packageManager; }; -async function ensureLegacyPeerDeps() { - //add legacy-peer-deps-support - switch (config.packageManager) { - case 'npm': - execSync('npm config --location=project set legacy-peer-deps=true'); - break; - case 'yarn': - execSync('yarn config set legacy-peer-deps true'); - break; - case 'pnpm': - execSync('pnpm config set legacy-peer-deps true'); - break; - case 'bun': - break; - } +async function ensureLegacyPeerDeps(): Promise { + const commands: { [key: string]: string } = { + npm: 'npm config --location=project set legacy-peer-deps=true', + yarn: 'yarn config set legacy-peer-deps true', + pnpm: 'pnpm config set legacy-peer-deps true', + }; + + const command = config.packageManager && commands[config.packageManager]; + if (command) execSync(command); } const installDependencies = async ( input: string[] | string, - additionalDependencies?: Dependencies | undefined + additionalDependencies?: ComponentConfig | undefined ): Promise => { try { await ensureLegacyPeerDeps(); - let versionManager: string | null; - if (!config.packageManager) { - versionManager = findLockFileType(); - if (!versionManager) { - versionManager = await promptVersionManager(); - } - config.packageManager = versionManager; - } else versionManager = config.packageManager; + let versionManager = + config.packageManager || + findLockFileType() || + (await promptVersionManager()); + config.packageManager = versionManager; + const dependenciesToInstall: { dependencies: Dependency; devDependencies: Dependency; @@ -295,76 +279,51 @@ const installDependencies = async ( }); }; + //get input based dependencies + if (input === '--all') gatherDependencies(Object.keys(dependenciesConfig)); + else if (Array.isArray(input)) gatherDependencies(input); + //generate install command - const generateInstallCommand = (deps: Dependency, flag: string): string => { - return ( - Object.entries(deps) - .map(([pkg, version]) => `${pkg}@${version}`) - .join(' ') + flag - ); + const generateInstallCommand = ( + deps: { [key: string]: string }, + flag: string + ): string => + Object.entries(deps) + .map(([pkg, version]) => `${pkg}@${version}`) + .join(' ') + flag; + + const commands: { [key: string]: { install: string; devFlag: string } } = { + npm: { install: 'npm install', devFlag: ' --save-dev' }, + yarn: { install: 'yarn add', devFlag: ' --dev' }, + pnpm: { install: 'pnpm i', devFlag: '' }, + bun: { install: 'bun add', devFlag: ' --dev' }, }; + const { install, devFlag } = commands[versionManager]; - //get input based dependencies - if (input === '--all') { - gatherDependencies(Object.keys(dependenciesConfig)); - } else if (Array.isArray(input)) { - gatherDependencies(input); - } + const installCommand = `${install} ${generateInstallCommand(dependenciesToInstall.dependencies, '')}`; + const devInstallCommand = `${install} ${generateInstallCommand(dependenciesToInstall.devDependencies, devFlag)}`; - let installCommand = '', - devInstallCommand = ''; - - switch (versionManager) { - case 'npm': - installCommand = `npm install ${generateInstallCommand(dependenciesToInstall.dependencies, '')}`; - devInstallCommand = `npm install ${generateInstallCommand(dependenciesToInstall.devDependencies, ' --save-dev')}`; - break; - case 'yarn': - installCommand = `yarn add ${generateInstallCommand(dependenciesToInstall.dependencies, '')}`; - devInstallCommand = `yarn add ${generateInstallCommand(dependenciesToInstall.devDependencies, ' --dev')}`; - break; - case 'pnpm': - installCommand = `pnpm i ${generateInstallCommand(dependenciesToInstall.dependencies, '')}`; - devInstallCommand = `pnpm i ${generateInstallCommand(dependenciesToInstall.devDependencies, '')}`; - break; - case 'bun': - installCommand = `bun add ${generateInstallCommand(dependenciesToInstall.dependencies, '')}`; - devInstallCommand = `bun add ${generateInstallCommand(dependenciesToInstall.devDependencies, ' --dev')}`; - break; - default: - throw new Error('Invalid package manager selected'); - } const s = spinner(); s.start( '⏳ Installing dependencies. This might take a couple of minutes...' ); try { - let depResult; - let devDepResult; - - if (Object.keys(dependenciesToInstall.dependencies || {}).length > 0) { - depResult = spawnSync(installCommand, { + if (Object.keys(dependenciesToInstall.dependencies).length > 0) { + spawnSync(installCommand, { cwd: currDir, stdio: 'inherit', shell: true, }); } - if (Object.keys(dependenciesToInstall.devDependencies || {}).length > 0) { - devDepResult = spawnSync(devInstallCommand, { + if (Object.keys(dependenciesToInstall.devDependencies).length > 0) { + spawnSync(devInstallCommand, { cwd: currDir, stdio: 'inherit', shell: true, }); } - if ( - (depResult && depResult.status) || - (devDepResult && devDepResult.status) - ) { - throw new Error(); - } - s.stop(`Dependencies have been installed successfully.`); } catch (err) { throw new Error('Error installing dependencies.'); @@ -378,63 +337,52 @@ const installDependencies = async ( //function to detect type of project async function detectProjectType(directoryPath: string): Promise { try { - // Check for files or directories unique to Next.js, Expo, or React Native CLI projects - const nextjsFiles: string[] = ['next.config.js', 'next.config.mjs']; - const expoFiles: string[] = ['app.json', 'app.config.js', 'app.config.ts']; - const reactNativeFiles: string[] = ['ios', 'android']; - const packageJsonPath = rootPackageJsonPath; - // Check for presence of Next.js files/directories - const isNextJs: boolean = await Promise.all( - nextjsFiles.map((file) => fs.pathExists(`${directoryPath}/${file}`)) - ).then((results) => results.some(Boolean)); - - // Check for presence of Expo files/directories - const isExpo: boolean = await Promise.all( - expoFiles.map((file) => fs.pathExists(`${directoryPath}/${file}`)) - ).then((results) => results.some(Boolean)); - - // Check for presence of React Native CLI files/directories - const isReactNative: boolean = await Promise.all( - reactNativeFiles.map((file) => fs.pathExists(`${directoryPath}/${file}`)) - ).then((results) => results.every(Boolean)); - - // Check for presence of package.json file - if (fs.existsSync(packageJsonPath) && packageJsonPath !== '') { - const packageJson = await fs.readJSONSync(packageJsonPath); - - // Determine the project type based on the presence of specific files/directories - if ( - isNextJs && - packageJson.dependencies && - packageJson.dependencies.next - ) { - const userConfirm = await getConfirmation( - 'Detected a Next JS project, continue?' - ); - if (userConfirm) return config.nextJsProject; + const fileChecks: { [key: string]: string[] } = { + nextjs: ['next.config.js', 'next.config.mjs'], + expo: ['app.json', 'app.config.js', 'app.config.ts'], + reactNative: ['ios', 'android'], + }; + + const checkFiles = async (files: string[]): Promise => + ( + await Promise.all( + files.map((file) => fs.pathExists(`${directoryPath}/${file}`)) + ) + ).some(Boolean); + + const isNextJs = await checkFiles(fileChecks.nextjs); + const isExpo = await checkFiles(fileChecks.expo); + const isReactNative = await checkFiles(fileChecks.reactNative); + + if (fs.existsSync(rootPackageJsonPath)) { + const packageJson = await fs.readJSON(rootPackageJsonPath); + const { dependencies } = packageJson; + + if (isNextJs && dependencies?.next) { + return (await getConfirmation('Detected a Next JS project, continue?')) + ? config.nextJsProject + : await getFrameworkInput(); } else if ( isExpo && - packageJson.dependencies && - packageJson.dependencies.expo && - packageJson.dependencies['react-native'] && - !packageJson.dependencies.next && + dependencies?.expo && + dependencies['react-native'] && + !dependencies.next && !isNextJs && !isReactNative ) { - const userConfirm = await getConfirmation( - 'Detected a Expo project, continue?' - ); - if (userConfirm) return config.expoProject; + return (await getConfirmation('Detected an Expo project, continue?')) + ? config.expoProject + : await getFrameworkInput(); } else if ( isReactNative && - packageJson.dependencies && - packageJson.dependencies['react-native'] && - !packageJson.dependencies.expo + dependencies['react-native'] && + !dependencies.expo ) { - const userConfirm = await getConfirmation( + return (await getConfirmation( 'Detected a React Native CLI project, continue?' - ); - if (userConfirm) return config.reactNativeCLIProject; + )) + ? config.reactNativeCLIProject + : await getFrameworkInput(); } } const frameworkInput = await getFrameworkInput(); @@ -482,52 +430,30 @@ async function getFrameworkInput(): Promise { return frameworkInput as string; } -// Function to get existing component style is not used in the current implementation -async function getExistingComponentStyle() { - //refactor this function so that we can directly fetch existing config path - if (fs.existsSync(join(currDir, config.UIconfigPath))) { - const fileContent: string = fs.readFileSync( - join(currDir, config.UIconfigPath), - 'utf8' - ); - // Define a regular expression pattern to match import statements - const importPattern: RegExp = new RegExp( - `import {\\s*\\w+\\s*} from ['"]nativewind['"]`, - 'g' - ); - if (importPattern.test(fileContent)) { - config.style = config.nativeWindRootPath; - return config.nativeWindRootPath; - } else { - config.style = config.gluestackStyleRootPath; - return config.gluestackStyleRootPath; - } - } -} - //function to return additional dependencies based on project type async function getAdditionalDependencies( projectType: string | undefined, style: string ) { try { - let additionalDependencies: { - dependencies: {}; - devDependencies?: {}; - } = { + let additionalDependencies: ComponentConfig = { dependencies: {}, devDependencies: {}, }; - if (style === config.nativeWindRootPath) { - if (projectType && projectType !== 'library') { - additionalDependencies.dependencies = - projectBasedDependencies[projectType].dependencies; - additionalDependencies.devDependencies = - projectBasedDependencies[projectType]?.devDependencies; - return additionalDependencies; - } else return {}; + if ( + style === config.nativeWindRootPath && + projectType && + projectType !== 'library' + ) { + additionalDependencies = { + dependencies: projectBasedDependencies[projectType].dependencies, + devDependencies: + projectBasedDependencies[projectType]?.devDependencies || {}, + }; } + additionalDependencies = { dependencies: {}, devDependencies: {} }; + return additionalDependencies; } catch (error) { log.error(`\x1b[31mError: ${(error as Error).message}\x1b[0m`); } @@ -545,11 +471,8 @@ const checkWritablePath = async (path: string): Promise => { \n\x1b[34m${join(projectRootPath, path)} \x1b[0m` ); - if (confirmPath) { - return true; - } else { - process.exit(1); - } + if (!confirmPath) process.exit(1); + return true; }; const checkIfFolderExists = async (path: string): Promise => { @@ -568,20 +491,6 @@ function removeHyphen(str: string): string { // Define a callback type type Callback = (error: Error | null, output: string | null) => void; -function runCliCommand(command: string, callback: Callback): void { - exec(command, (error, stdout, stderr) => { - if (error) { - callback(error, null); - return; - } - if (stderr) { - callback(new Error(stderr), null); - return; - } - callback(null, stdout); - }); -} - function getRelativePath({ sourcePath, targetPath, @@ -593,14 +502,9 @@ function getRelativePath({ const targetDir = dirname(targetPath); let relativePath = relative(sourceDir, targetDir); - // If the relative path is '.' or empty, it means the directories are the same - if (relativePath === '.' || relativePath === '') { - // Files are in the same directory - return './' + basename(targetPath); - } else { - // Construct the full relative path - return join(relativePath, basename(targetPath)); - } + return relativePath === '.' || relativePath === '' + ? './' + basename(targetPath) + : join(relativePath, basename(targetPath)); } async function ensureFilesPromise(filePaths: string[]): Promise { diff --git a/packages/gluestack-cli/template/codemods/expo/babel-config-transform.ts b/packages/gluestack-cli/template/codemods/expo/babel-config-transform.ts index 11fb06c7..6b923279 100644 --- a/packages/gluestack-cli/template/codemods/expo/babel-config-transform.ts +++ b/packages/gluestack-cli/template/codemods/expo/babel-config-transform.ts @@ -93,7 +93,7 @@ const transform: Transform = (file, api, options): string => { j.objectExpression([ j.objectProperty(j.stringLiteral('@'), j.stringLiteral('./')), j.objectProperty( - j.stringLiteral('tailwindConfig'), + j.stringLiteral('tailwind.config'), j.stringLiteral(`./` + tailwindConfigFileName) ), ]) diff --git a/packages/gluestack/src/v2.ts b/packages/gluestack/src/v2.ts index ef9b4775..979a2ddd 100644 --- a/packages/gluestack/src/v2.ts +++ b/packages/gluestack/src/v2.ts @@ -64,11 +64,11 @@ async function createProject(createOptions: ProjectOptions) { } async function initializeGluestack(projectOptions: ProjectOptions) { - const { projectName, projectType } = projectOptions; + const { projectName, projectType, packageManager } = projectOptions; try { - execSync(`cd ${projectName}`, { stdio: 'inherit' }); + process.chdir(projectName); execSync( - `npx gluestack-ui@alpha init --template-only --projectType ${projectType}`, + `npx gluestack-ui@alpha init --template-only --projectType ${projectType} --use-${packageManager}`, { stdio: 'inherit' } ); execSync(`npx gluestack-ui@alpha add --all`, { @@ -205,7 +205,7 @@ export async function main(args: string[]) { // await cloneProject(projName, templateDir); // await installDependencies(projName, selectedPackageManager); await createProject(createOptions); - // await initializeGluestack(createOptions); + await initializeGluestack(createOptions); console.log('done ...'); } catch { console.log('Failed to create project'); From 1a1152672dac38ddd4b6f1f46951ba68c12d0a59 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Tue, 1 Oct 2024 15:04:47 +0530 Subject: [PATCH 25/71] v0.7.10-alpha.0.5 --- packages/gluestack-cli/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gluestack-cli/package.json b/packages/gluestack-cli/package.json index c575917d..65c9c70f 100644 --- a/packages/gluestack-cli/package.json +++ b/packages/gluestack-cli/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for easily adding components from gluestack to your projects.", - "version": "0.7.10-alpha.0.4", + "version": "0.7.10-alpha.0.5", "license": "MIT", "main": "dist/index.js", "files": [ From 9bce579df90fed615a5e7e1c853db5cf0efd0c17 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Tue, 1 Oct 2024 15:05:09 +0530 Subject: [PATCH 26/71] v2.0.1-alpha.0.8 --- packages/gluestack/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gluestack/package.json b/packages/gluestack/package.json index 5ec82259..db01eba5 100644 --- a/packages/gluestack/package.json +++ b/packages/gluestack/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for working with gluestack", - "version": "2.0.1-alpha.0.7", + "version": "2.0.1-alpha.0.8", "license": "MIT", "main": "./dist/index.js", "bin": "./dist/index.js", From 6f74359981306ca9db936555ba71bc60740a6657 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Tue, 1 Oct 2024 15:19:24 +0530 Subject: [PATCH 27/71] v2.0.1-alpha.0.9 --- packages/gluestack/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gluestack/package.json b/packages/gluestack/package.json index db01eba5..bc961222 100644 --- a/packages/gluestack/package.json +++ b/packages/gluestack/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for working with gluestack", - "version": "2.0.1-alpha.0.8", + "version": "2.0.1-alpha.0.9", "license": "MIT", "main": "./dist/index.js", "bin": "./dist/index.js", From d97b61872708671d3ab2bd7477a4bac18752f02f Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Tue, 1 Oct 2024 15:42:46 +0530 Subject: [PATCH 28/71] v2.0.1-alpha.1.0 --- packages/gluestack/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gluestack/package.json b/packages/gluestack/package.json index bc961222..eea9c089 100644 --- a/packages/gluestack/package.json +++ b/packages/gluestack/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for working with gluestack", - "version": "2.0.1-alpha.0.9", + "version": "2.0.1-alpha.1.0", "license": "MIT", "main": "./dist/index.js", "bin": "./dist/index.js", From 85380f3d6d8f377874faaf2f84e99ae2a9448c48 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Tue, 1 Oct 2024 15:46:40 +0530 Subject: [PATCH 29/71] fix: create gluestack tests --- packages/gluestack-cli/src/commands/add.ts | 7 ++++ packages/gluestack-cli/src/util/add/index.ts | 13 +++---- packages/gluestack-cli/src/util/index.ts | 4 +- packages/gluestack/src/data.js | 2 +- packages/gluestack/src/v2.ts | 41 +++++++++++++------- 5 files changed, 41 insertions(+), 26 deletions(-) diff --git a/packages/gluestack-cli/src/commands/add.ts b/packages/gluestack-cli/src/commands/add.ts index e9f2f314..e551d954 100644 --- a/packages/gluestack-cli/src/commands/add.ts +++ b/packages/gluestack-cli/src/commands/add.ts @@ -1,17 +1,22 @@ import { Command } from 'commander'; import { z } from 'zod'; +import os from 'os'; +import { join } from 'path'; import { handleError } from '../util/handle-error'; import { log } from '@clack/prompts'; import { componentAdder, hookAdder, isHookFromConfig } from '../util/add'; import { config } from '../config'; import { checkWritablePath, + cloneRepositoryAtRoot, getPackageMangerFlag, isValidPath, projectRootPath, } from '../util'; import { checkIfInitialized, getComponentsPath } from '../util/config'; +const _homeDir = os.homedir(); + const addOptionsSchema = z.object({ components: z.string().optional(), all: z.boolean(), @@ -88,6 +93,8 @@ export const add = new Command() await checkWritablePath(options.path); config.writableComponentsPath = options.path; } + await cloneRepositoryAtRoot(join(_homeDir, config.gluestackDir)); + if (options.all) { try { await componentAdder({ diff --git a/packages/gluestack-cli/src/util/add/index.ts b/packages/gluestack-cli/src/util/add/index.ts index a1b6706a..008fd110 100644 --- a/packages/gluestack-cli/src/util/add/index.ts +++ b/packages/gluestack-cli/src/util/add/index.ts @@ -4,7 +4,7 @@ import { basename, join, parse } from 'path'; import { log, confirm } from '@clack/prompts'; import { config } from '../../config'; import { - checkAdditionalDependencies, + checkComponentDependencies, cloneRepositoryAtRoot, getAllComponents, installDependencies, @@ -21,7 +21,6 @@ const componentAdder = async ({ }) => { try { console.log(`\n\x1b[1mAdding new component...\x1b[0m\n`); - await cloneRepositoryAtRoot(join(_homeDir, config.gluestackDir)); let hooksToAdd: string[] = []; if ( requestedComponent && @@ -38,13 +37,14 @@ const componentAdder = async ({ ? getAllComponents() : [requestedComponent]; - const { hooks } = checkAdditionalDependencies(requestedComponents); + const { hooks } = checkComponentDependencies(requestedComponents); hooksToAdd = Array.from(hooks); const updatedComponents = !existingComponentsChecked && showWarning && requestedComponent ? await isComponentInProject(requestedComponents) : requestedComponents; + const count = updatedComponents.length; await Promise.all( updatedComponents.map(async (component) => { const targetPath = join( @@ -54,19 +54,18 @@ const componentAdder = async ({ ); await writeComponent(component, targetPath); - if (hooksToAdd.length > 0) - await hookAdder({ requestedHook: hooksToAdd }); }) ) .then(async () => { await installDependencies(updatedComponents); log.success( - `\x1b[32mDone!\x1b[0m Added new \x1b[1mgluestack-ui\x1b[0m component into project` + `\x1b[32mDone!\x1b[0m Added new \x1b[1mgluestack-ui\x1b[0m ${count === 1 ? 'component' : 'components'} into project` ); }) .catch((err) => { log.error(`\x1b[31mError : ${(err as Error).message}\x1b[0m`); }); + if (hooksToAdd.length > 0) await hookAdder({ requestedHook: hooksToAdd }); } catch (err) { log.error(`\x1b[31mError: ${(err as Error).message}\x1b[0m`); } @@ -174,8 +173,6 @@ const hookAdder = async ({ }) => { try { console.log(`\n\x1b[1mAdding new hook...\x1b[0m\n`); - await cloneRepositoryAtRoot(join(_homeDir, config.gluestackDir)); - await writeHook(requestedHook); log.success( `\x1b[32mDone!\x1b[0m Added new \x1b[1mgluestack-ui\x1b[0m hook into project` diff --git a/packages/gluestack-cli/src/util/index.ts b/packages/gluestack-cli/src/util/index.ts index 1a438990..8da9a409 100644 --- a/packages/gluestack-cli/src/util/index.ts +++ b/packages/gluestack-cli/src/util/index.ts @@ -59,7 +59,7 @@ interface AdditionalDependencies { hooks: string[]; } -function checkAdditionalDependencies( +function checkComponentDependencies( components: string[] ): AdditionalDependencies { const additionalDependencies: AdditionalDependencies = { @@ -535,5 +535,5 @@ export { getRelativePath, ensureFilesPromise, getPackageMangerFlag, - checkAdditionalDependencies, + checkComponentDependencies, }; diff --git a/packages/gluestack/src/data.js b/packages/gluestack/src/data.js index 6b352727..b798c5e9 100644 --- a/packages/gluestack/src/data.js +++ b/packages/gluestack/src/data.js @@ -21,7 +21,7 @@ module.exports = { ], }, Route: { - next: { + nextjs: { question: 'Would you like to use \x1b[36mApp Router\x1b[0m?', options: [ { diff --git a/packages/gluestack/src/v2.ts b/packages/gluestack/src/v2.ts index 979a2ddd..714e6dc4 100644 --- a/packages/gluestack/src/v2.ts +++ b/packages/gluestack/src/v2.ts @@ -1,6 +1,6 @@ #! /usr/bin/env node import path from 'path'; -import { cancel, text, select } from '@clack/prompts'; +import { cancel, text, select, log } from '@clack/prompts'; import chalk from 'chalk'; import { execSync } from 'child_process'; import { displayHelp } from './help'; @@ -20,27 +20,25 @@ interface ProjectOptions { async function createProject(createOptions: ProjectOptions) { const { projectName, projectType, packageManager, router } = createOptions; let createCommand = ''; - console.log(`Creating project: ${chalk.blue(projectName)}`); - if (projectType.includes('expo')) { // create expo project const templateFlag = router.includes('expo-router') - ? `blank-typescript` + ? `--template blank-typescript` : ``; switch (packageManager) { case 'npm': - createCommand = `npx create-expo-app@latest ${projectName} --template ${templateFlag}`; + createCommand = `npx create-expo-app@latest ${projectName} ${templateFlag}`; break; case 'yarn': - createCommand = `yarn create expo-app ${projectName} --template ${templateFlag}`; + createCommand = `yarn create expo-app ${projectName} ${templateFlag}`; break; case 'pnpm': - createCommand = `pnpm create expo-app ${projectName} --template ${templateFlag}`; + createCommand = `pnpm create expo-app ${projectName} ${templateFlag}`; break; case 'bun': - createCommand = `bun create expo ${projectName} --template ${templateFlag}`; + createCommand = `bun create expo ${projectName} ${templateFlag}`; break; } } else if (projectType.includes('nextjs')) { @@ -55,8 +53,8 @@ async function createProject(createOptions: ProjectOptions) { createCommand = `npx @react-native-community/cli@latest init ${projectName} --pm ${packageManager}`; } try { - execSync(createCommand, { stdio: 'inherit' }); - console.log(`Successfully created project: ${projectName}`); + execSync(createCommand); + console.log(chalk.bold(`✅ Your project is ready!`)); } catch (e) { console.error(`Failed to create project: ${e}`); throw e; @@ -75,7 +73,7 @@ async function initializeGluestack(projectOptions: ProjectOptions) { stdio: 'inherit', }); } catch (e) { - console.log('Failed to initialize gluestack-ui'); + console.error('Failed to initialize gluestack-ui'); throw e; } } @@ -96,7 +94,7 @@ export async function main(args: string[]) { '--expo-router', '--next-app-router', '--next-page-router', - '--react-native', + '--react-native-cli', ]; const supportedStyleArgs = ['--gs', '--nw']; const supportedPackagemanagers = ['npm', 'yarn', 'pnpm', 'bun']; @@ -149,7 +147,7 @@ export async function main(args: string[]) { options: [...optionsType], }); templateName = selectedFramework; - if (selectedFramework !== 'react-native') { + if (selectedFramework !== 'react-native-cli') { const { question, options: optionsType } = // @ts-ignore options.framework.Route[selectedFramework]; @@ -193,13 +191,26 @@ export async function main(args: string[]) { selectedPackageManager = 'npm'; } } + + // Add this check after determining the framework and package manager + if ( + selectedFramework === 'react-native-cli' && + selectedPackageManager === 'pnpm' + ) { + log.warn( + chalk.yellow( + 'React Native CLI does not officially support pnpm as a package manager. It is recommended to use npm or yarn instead.' + ) + ); + process.exit(1); + } + const createOptions: ProjectOptions = { projectType: selectedFramework, router: selectedRouter as RouterType, packageManager: selectedPackageManager as PackageManager, projectName: projName, }; - console.log('createOptions--->', createOptions); try { // @ts-ignore // await cloneProject(projName, templateDir); @@ -208,7 +219,7 @@ export async function main(args: string[]) { await initializeGluestack(createOptions); console.log('done ...'); } catch { - console.log('Failed to create project'); + console.error('Failed to create project'); process.exit(1); } } From 3f2d6a4f695b087f5ecc8879a9b6784b88c4d949 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Tue, 1 Oct 2024 16:40:43 +0530 Subject: [PATCH 30/71] v0.7.10-alpha.0.6 --- packages/gluestack-cli/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gluestack-cli/package.json b/packages/gluestack-cli/package.json index 65c9c70f..6939ffc7 100644 --- a/packages/gluestack-cli/package.json +++ b/packages/gluestack-cli/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for easily adding components from gluestack to your projects.", - "version": "0.7.10-alpha.0.5", + "version": "0.7.10-alpha.0.6", "license": "MIT", "main": "dist/index.js", "files": [ From de4c54f357bdddfb48fb397ce3d5fe681b4a7267 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Tue, 1 Oct 2024 18:58:45 +0530 Subject: [PATCH 31/71] v0.7.10-alpha.0.7 --- packages/gluestack-cli/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gluestack-cli/package.json b/packages/gluestack-cli/package.json index 6939ffc7..826d9b6a 100644 --- a/packages/gluestack-cli/package.json +++ b/packages/gluestack-cli/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for easily adding components from gluestack to your projects.", - "version": "0.7.10-alpha.0.6", + "version": "0.7.10-alpha.0.7", "license": "MIT", "main": "dist/index.js", "files": [ From 5b9257a58c5cddb68849dda0a97400c58d800738 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Tue, 1 Oct 2024 18:59:28 +0530 Subject: [PATCH 32/71] v2.0.1-alpha.1.1 --- packages/gluestack/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gluestack/package.json b/packages/gluestack/package.json index eea9c089..67d0366e 100644 --- a/packages/gluestack/package.json +++ b/packages/gluestack/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for working with gluestack", - "version": "2.0.1-alpha.1.0", + "version": "2.0.1-alpha.1.1", "license": "MIT", "main": "./dist/index.js", "bin": "./dist/index.js", From 080f3fc683c741ab7bba80121e47443600adc2c1 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Tue, 1 Oct 2024 18:59:54 +0530 Subject: [PATCH 33/71] feat: alpha release --- packages/gluestack-cli/src/commands/init.ts | 2 +- packages/gluestack-cli/src/dependencies.ts | 2 +- packages/gluestack-cli/src/util/index.ts | 10 +++++++--- packages/gluestack/src/v2.ts | 4 ++-- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/packages/gluestack-cli/src/commands/init.ts b/packages/gluestack-cli/src/commands/init.ts index 0778b68b..11fd79fc 100644 --- a/packages/gluestack-cli/src/commands/init.ts +++ b/packages/gluestack-cli/src/commands/init.ts @@ -81,7 +81,7 @@ export const init = new Command() if (options.path !== config.writableComponentsPath) { await checkWritablePath(options.path); //check this change with all project types - config.writableComponentsPath = resolve(cwd, options.path); + config.writableComponentsPath = options.path; } } // Detect project type diff --git a/packages/gluestack-cli/src/dependencies.ts b/packages/gluestack-cli/src/dependencies.ts index bbaddeed..e740a372 100644 --- a/packages/gluestack-cli/src/dependencies.ts +++ b/packages/gluestack-cli/src/dependencies.ts @@ -21,7 +21,7 @@ const projectBasedDependencies: Dependencies = { '@gluestack/ui-next-adapter': 'latest', }, devDependencies: { - '@types/react-native': '', + '@types/react-native': '0.72.8', }, }, expo: { diff --git a/packages/gluestack-cli/src/util/index.ts b/packages/gluestack-cli/src/util/index.ts index 8da9a409..cad09d19 100644 --- a/packages/gluestack-cli/src/util/index.ts +++ b/packages/gluestack-cli/src/util/index.ts @@ -72,12 +72,16 @@ function checkComponentDependencies( // Add additional components config.additionalComponents?.forEach((additionalComponent) => { - additionalDependencies.components.push(additionalComponent); + if (!additionalDependencies.components.includes(additionalComponent)) { + additionalDependencies.components.push(additionalComponent); + } }); // Add hooks config.hooks?.forEach((hook) => { - additionalDependencies.hooks.push(hook); + if (!additionalDependencies.hooks.includes(hook)) { + additionalDependencies.hooks.push(hook); + } }); }); @@ -295,7 +299,7 @@ const installDependencies = async ( const commands: { [key: string]: { install: string; devFlag: string } } = { npm: { install: 'npm install', devFlag: ' --save-dev' }, yarn: { install: 'yarn add', devFlag: ' --dev' }, - pnpm: { install: 'pnpm i', devFlag: '' }, + pnpm: { install: 'pnpm i', devFlag: '-D' }, bun: { install: 'bun add', devFlag: ' --dev' }, }; const { install, devFlag } = commands[versionManager]; diff --git a/packages/gluestack/src/v2.ts b/packages/gluestack/src/v2.ts index 714e6dc4..a424694d 100644 --- a/packages/gluestack/src/v2.ts +++ b/packages/gluestack/src/v2.ts @@ -45,8 +45,8 @@ async function createProject(createOptions: ProjectOptions) { // create next project createCommand = projectType.includes('next-page-router') - ? `npx create-next-app@latest ${projectName} --ts --no-eslint --use-${packageManager} --import-alias "@/*" --tailwind --no-src-dir --no-app` - : `npx create-next-app@latest ${projectName} --ts --no-eslint --use-${packageManager} --import-alias "@/*" --tailwind --no-src-dir --app`; + ? `npx create-next-app@latest ${projectName} --ts --no-eslint --use-${packageManager} --import-alias "@/*" --no-tailwind --no-src-dir --no-app` + : `npx create-next-app@latest ${projectName} --ts --no-eslint --use-${packageManager} --import-alias "@/*" --no-tailwind --no-src-dir --app`; } else if (projectType.includes('react-native')) { // create react-native project From d8c665ecc0c178bf8a6eb76fdd5bdb0295ce0750 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Thu, 3 Oct 2024 16:15:40 +0530 Subject: [PATCH 34/71] v2.0.1-alpha.1.2 --- packages/gluestack/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gluestack/package.json b/packages/gluestack/package.json index 67d0366e..29392ab3 100644 --- a/packages/gluestack/package.json +++ b/packages/gluestack/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for working with gluestack", - "version": "2.0.1-alpha.1.1", + "version": "2.0.1-alpha.1.2", "license": "MIT", "main": "./dist/index.js", "bin": "./dist/index.js", From e1508902cd4d441aa8ad4883ec04dd2666b366b6 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Thu, 3 Oct 2024 16:41:51 +0530 Subject: [PATCH 35/71] v0.7.10-alpha.0.8 --- packages/gluestack-cli/package.json | 2 +- packages/gluestack/src/v2.ts | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/gluestack-cli/package.json b/packages/gluestack-cli/package.json index 826d9b6a..7f882829 100644 --- a/packages/gluestack-cli/package.json +++ b/packages/gluestack-cli/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for easily adding components from gluestack to your projects.", - "version": "0.7.10-alpha.0.7", + "version": "0.7.10-alpha.0.8", "license": "MIT", "main": "dist/index.js", "files": [ diff --git a/packages/gluestack/src/v2.ts b/packages/gluestack/src/v2.ts index a424694d..f2fbb210 100644 --- a/packages/gluestack/src/v2.ts +++ b/packages/gluestack/src/v2.ts @@ -1,6 +1,6 @@ #! /usr/bin/env node import path from 'path'; -import { cancel, text, select, log } from '@clack/prompts'; +import { cancel, text, select, log, spinner } from '@clack/prompts'; import chalk from 'chalk'; import { execSync } from 'child_process'; import { displayHelp } from './help'; @@ -24,8 +24,8 @@ async function createProject(createOptions: ProjectOptions) { // create expo project const templateFlag = router.includes('expo-router') - ? `--template blank-typescript` - : ``; + ? `` + : `--template blank-typescript`; switch (packageManager) { case 'npm': @@ -53,8 +53,10 @@ async function createProject(createOptions: ProjectOptions) { createCommand = `npx @react-native-community/cli@latest init ${projectName} --pm ${packageManager}`; } try { + const s = spinner(); + s.start('⏳ Initializing project. This might take a couple of minutes...'); execSync(createCommand); - console.log(chalk.bold(`✅ Your project is ready!`)); + s.stop(chalk.bold(`✅ Your project is ready!`)); } catch (e) { console.error(`Failed to create project: ${e}`); throw e; From 4c3175a1f1570b1154cf68dfc1ddb91c0472cd9b Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Fri, 4 Oct 2024 11:58:53 +0530 Subject: [PATCH 36/71] feat: using JSON from gluestack-ui --- packages/gluestack-cli/src/config.ts | 6 +- packages/gluestack-cli/src/dependencies.ts | 273 +++++------------- packages/gluestack-cli/src/util/add/index.ts | 7 +- packages/gluestack-cli/src/util/index.ts | 94 ++---- packages/gluestack-cli/src/util/init/index.ts | 9 +- 5 files changed, 105 insertions(+), 284 deletions(-) diff --git a/packages/gluestack-cli/src/config.ts b/packages/gluestack-cli/src/config.ts index 80a21640..7ca1b5f9 100644 --- a/packages/gluestack-cli/src/config.ts +++ b/packages/gluestack-cli/src/config.ts @@ -3,19 +3,17 @@ const config = { gluestackDir: '.gluestack/cache/gluestack-ui', componentsResourcePath: 'example/storybook-nativewind/src/core-components', hooksResourcePath: 'example/storybook-nativewind/src/core-components/hooks', - gluestackStyleRootPath: 'themed', + dependencyConfigPath: + 'example/storybook-nativewind/src/core-components/nativewind/dependencies.json', nativeWindRootPath: 'nativewind', expoProject: 'expo', nextJsProject: 'nextjs', reactNativeCLIProject: 'react-native-cli', tailwindConfigRootPath: 'example/storybook-nativewind/src/tailwind.config.js', - UIconfigPath: 'gluestack-ui-provider/config.ts', writableComponentsPath: 'components/ui', branchName: 'patch', - tagName: '@gluestack-ui/storybook@0.1.0', style: 'nativewind', providerComponent: 'gluestack-ui-provider', - configFileName: 'config.ts', nativewindUtilPattern: '@gluestack-ui/nativewind-utils/', gluestackUIPattern: '@gluestack-ui/', templatesDir: '../../../template', diff --git a/packages/gluestack-cli/src/dependencies.ts b/packages/gluestack-cli/src/dependencies.ts index e740a372..7aab3499 100644 --- a/packages/gluestack-cli/src/dependencies.ts +++ b/packages/gluestack-cli/src/dependencies.ts @@ -1,3 +1,11 @@ +import { join } from 'path'; +import { config } from './config'; +import { log } from '@clack/prompts'; +import fs from 'fs-extra'; +import os from 'os'; + +const __homeDir = os.homedir(); + export interface Dependency { [key: string]: string; } @@ -12,6 +20,11 @@ export interface Dependencies { [key: string]: ComponentConfig; } +interface UIConfigJSON { + components: Dependencies; + IgnoredComponents: string[]; +} + const projectBasedDependencies: Dependencies = { nextjs: { dependencies: { @@ -38,213 +51,59 @@ const projectBasedDependencies: Dependencies = { }, }, }; -const dependenciesConfig: Dependencies = { - 'gluestack-ui-provider': { - dependencies: { - tailwindcss: '', - '@gluestack-ui/overlay': 'latest', - '@gluestack-ui/toast': 'latest', - '@gluestack-ui/nativewind-utils': 'latest', - 'react-native-svg': '13.4.0', - nativewind: '4.1.10', - }, - devDependencies: { - jscodeshift: '0.15.2', - prettier: '', - }, - }, - accordion: { - dependencies: { - '@gluestack-ui/accordion': 'latest', - '@expo/html-elements': '0.4.2', - }, - }, - actionsheet: { - dependencies: { - '@legendapp/motion': 'latest', - '@gluestack-ui/actionsheet': 'latest', - }, - }, - alert: { - dependencies: { - '@gluestack-ui/alert': 'latest', - }, - }, - 'alert-dialog': { - dependencies: { - '@gluestack-ui/alert-dialog': 'latest', - '@legendapp/motion': 'latest', - }, - }, - avatar: { - dependencies: { - '@gluestack-ui/avatar': 'latest', - }, - }, - badge: { dependencies: {} }, - box: { dependencies: {} }, - button: { - dependencies: { - '@gluestack-ui/button': 'latest', - }, - }, - card: { dependencies: {} }, - center: { dependencies: {} }, - checkbox: { - dependencies: { - '@gluestack-ui/checkbox': 'latest', - }, - }, - divider: { - dependencies: { - '@gluestack-ui/divider': 'latest', - }, - }, - fab: { - dependencies: { - '@gluestack-ui/fab': 'latest', - }, - }, - 'flat-list': { - dependencies: {}, - }, - 'form-control': { - dependencies: { - '@gluestack-ui/form-control': 'latest', - }, - }, - heading: { - dependencies: { - '@expo/html-elements': '0.4.2', - }, - }, - hstack: { - dependencies: {}, - }, - icon: { - dependencies: { - '@gluestack-ui/icon': 'latest', - }, - }, - image: { - dependencies: { - '@gluestack-ui/image': 'latest', - }, - }, - 'image-background': { - dependencies: {}, - }, - input: { - dependencies: { - '@gluestack-ui/input': 'latest', - }, - }, - 'input-accessory-view': { - dependencies: {}, - }, - 'keyboard-avoiding-view': { - dependencies: {}, - }, - link: { - dependencies: { - '@gluestack-ui/link': 'latest', - }, - }, - menu: { - dependencies: { - '@gluestack-ui/menu': 'latest', - '@legendapp/motion': 'latest', - }, - }, - modal: { - dependencies: { - '@gluestack-ui/modal': 'latest', - '@legendapp/motion': 'latest', - }, - }, - popover: { - dependencies: { - '@gluestack-ui/popover': 'latest', - '@legendapp/motion': 'latest', - }, - }, - pressable: { - dependencies: { - '@gluestack-ui/pressable': 'latest', - }, - }, - progress: { - dependencies: { - '@gluestack-ui/progress': 'latest', - }, - }, - radio: { - dependencies: { - '@gluestack-ui/radio': 'latest', - }, - }, - 'refresh-control': { dependencies: {} }, - 'safe-area-view': { dependencies: {} }, - 'scroll-view': { dependencies: {} }, - 'section-list': { - dependencies: {}, - }, - select: { - dependencies: { - '@gluestack-ui/select': 'latest', - '@gluestack-ui/actionsheet': 'latest', - '@legendapp/motion': 'latest', - '@expo/html-elements': '0.4.2', - }, - }, - slider: { - dependencies: { - '@gluestack-ui/slider': 'latest', - }, - }, - spinner: { - dependencies: { - '@gluestack-ui/spinner': 'latest', - }, - }, - 'status-bar': { dependencies: {} }, - switch: { - dependencies: { - '@gluestack-ui/switch': 'latest', - }, - }, - text: { dependencies: {} }, - textarea: { - dependencies: { - '@gluestack-ui/textarea': 'latest', - }, - }, - toast: { - dependencies: { - '@gluestack-ui/toast': 'latest', - '@legendapp/motion': 'latest', - }, - }, - tooltip: { - dependencies: { - '@gluestack-ui/tooltip': 'latest', - '@legendapp/motion': 'latest', - }, - }, - view: { dependencies: {} }, - 'virtualized-list': { dependencies: {} }, - vstack: { dependencies: {} }, - grid: { - dependencies: {}, - hooks: ['useBreakpointValue'], - }, -}; + +// Get dependency JSON +async function getDependencyJSON(): Promise { + const dependencyJSONPath = join( + __homeDir, + config.gluestackDir, + config.dependencyConfigPath + ); + if (!fs.existsSync(dependencyJSONPath)) { + log.error( + `\x1b[31mError: Dependency JSON file not found at ${dependencyJSONPath}\x1b[0m` + ); + process.exit; + } + const dependencyJSON = await fs.readJSON(dependencyJSONPath); + return dependencyJSON; +} + +// Get project based dependencies +async function getProjectBasedDependencies( + projectType: string | undefined, + style: string +) { + try { + if ( + style === config.nativeWindRootPath && + projectType && + projectType !== 'library' + ) { + return { + dependencies: projectBasedDependencies[projectType].dependencies, + devDependencies: + projectBasedDependencies[projectType]?.devDependencies || {}, + }; + } + return { dependencies: {}, devDependencies: {} }; + } catch (error) { + log.error(`\x1b[31mError: ${(error as Error).message}\x1b[0m`); + } +} // Ignore components that are in development or not in supported list -const IgnoredComponents = ['bottomsheet']; +const getIgnoredComponents = async (): Promise => { + const dependencyJSON = await getDependencyJSON(); + return dependencyJSON.IgnoredComponents; +}; -const getComponentDependencies = (componentName: string): ComponentConfig => { - const config = dependenciesConfig[componentName]; +// Get dependencies for a component +const getComponentDependencies = async ( + componentName: string +): Promise => { + const dependencyJSON = await getDependencyJSON(); + const config = dependencyJSON.components[componentName]; if (!config) { return { dependencies: {}, @@ -260,9 +119,9 @@ const getComponentDependencies = (componentName: string): ComponentConfig => { hooks: config.hooks || [], }; }; + export { - dependenciesConfig, - projectBasedDependencies, - IgnoredComponents, + getIgnoredComponents, getComponentDependencies, + getProjectBasedDependencies, }; diff --git a/packages/gluestack-cli/src/util/add/index.ts b/packages/gluestack-cli/src/util/add/index.ts index 008fd110..6b0a91ea 100644 --- a/packages/gluestack-cli/src/util/add/index.ts +++ b/packages/gluestack-cli/src/util/add/index.ts @@ -5,7 +5,6 @@ import { log, confirm } from '@clack/prompts'; import { config } from '../../config'; import { checkComponentDependencies, - cloneRepositoryAtRoot, getAllComponents, installDependencies, projectRootPath, @@ -34,10 +33,10 @@ const componentAdder = async ({ } let requestedComponents = requestedComponent === '--all' - ? getAllComponents() + ? await getAllComponents() : [requestedComponent]; - const { hooks } = checkComponentDependencies(requestedComponents); + const { hooks } = await checkComponentDependencies(requestedComponents); hooksToAdd = Array.from(hooks); const updatedComponents = @@ -123,7 +122,7 @@ const processTerminate = (message: string) => { }; const checkIfComponentIsValid = async (component: string): Promise => { - const componentList = getAllComponents(); + const componentList = await getAllComponents(); if (componentList.includes(component) || componentList.includes(component)) return true; else return false; diff --git a/packages/gluestack-cli/src/util/index.ts b/packages/gluestack-cli/src/util/index.ts index cad09d19..3c73293c 100644 --- a/packages/gluestack-cli/src/util/index.ts +++ b/packages/gluestack-cli/src/util/index.ts @@ -16,10 +16,8 @@ import { import { ComponentConfig, Dependency, - IgnoredComponents, - dependenciesConfig, + getIgnoredComponents, getComponentDependencies, - projectBasedDependencies, } from '../dependencies'; const homeDir = os.homedir(); @@ -33,7 +31,8 @@ const getPackageJsonPath = (): string => { const rootPackageJsonPath = getPackageJsonPath(); const projectRootPath: string = dirname(rootPackageJsonPath); -const getAllComponents = (): string[] => { +const getAllComponents = async (): Promise => { + const ignore = await getIgnoredComponents(); const componentList = fs .readdirSync( join( @@ -49,7 +48,7 @@ const getAllComponents = (): string[] => { extname(file).toLowerCase() ) && file !== config.providerComponent && - !IgnoredComponents.includes(file) + !ignore.includes(file) ); return componentList; }; @@ -59,32 +58,30 @@ interface AdditionalDependencies { hooks: string[]; } -function checkComponentDependencies( +async function checkComponentDependencies( components: string[] -): AdditionalDependencies { +): Promise { const additionalDependencies: AdditionalDependencies = { components: [], hooks: [], }; - components.forEach((component) => { - const config = getComponentDependencies(component); - + for (const component of components) { + const dependencyConfig = await getComponentDependencies(component); // Add additional components - config.additionalComponents?.forEach((additionalComponent) => { + dependencyConfig.additionalComponents?.forEach((additionalComponent) => { if (!additionalDependencies.components.includes(additionalComponent)) { additionalDependencies.components.push(additionalComponent); } }); // Add hooks - config.hooks?.forEach((hook) => { + dependencyConfig.hooks?.forEach((hook) => { if (!additionalDependencies.hooks.includes(hook)) { additionalDependencies.hooks.push(hook); } }); - }); - + } return additionalDependencies; } @@ -266,26 +263,27 @@ const installDependencies = async ( } //get dependencies from config - const gatherDependencies = (components: string[]): void => { - components.forEach((component) => { - if (dependenciesConfig[component]) { - Object.assign( - dependenciesToInstall.dependencies, - dependenciesConfig[component].dependencies - ); - if (dependenciesConfig[component].devDependencies) { - Object.assign( - dependenciesToInstall.devDependencies, - dependenciesConfig[component].devDependencies - ); - } - } - }); + const gatherDependencies = async ( + components: string[] + ): Promise<{ + dependencies: Dependency; + devDependencies: Dependency; + }> => { + for (const component of components) { + const config = await getComponentDependencies(component); + // Add dependencies + Object.assign(dependenciesToInstall.dependencies, config.dependencies); + // Add devDependencies + Object.assign( + dependenciesToInstall?.devDependencies, + config?.devDependencies + ); + } + return dependenciesToInstall; }; - //get input based dependencies - if (input === '--all') gatherDependencies(Object.keys(dependenciesConfig)); - else if (Array.isArray(input)) gatherDependencies(input); + if (input === '--all') await gatherDependencies(await getAllComponents()); + else if (Array.isArray(input)) await gatherDependencies(input); //generate install command const generateInstallCommand = ( @@ -299,7 +297,7 @@ const installDependencies = async ( const commands: { [key: string]: { install: string; devFlag: string } } = { npm: { install: 'npm install', devFlag: ' --save-dev' }, yarn: { install: 'yarn add', devFlag: ' --dev' }, - pnpm: { install: 'pnpm i', devFlag: '-D' }, + pnpm: { install: 'pnpm i', devFlag: ' -D' }, bun: { install: 'bun add', devFlag: ' --dev' }, }; const { install, devFlag } = commands[versionManager]; @@ -434,35 +432,6 @@ async function getFrameworkInput(): Promise { return frameworkInput as string; } -//function to return additional dependencies based on project type -async function getAdditionalDependencies( - projectType: string | undefined, - style: string -) { - try { - let additionalDependencies: ComponentConfig = { - dependencies: {}, - devDependencies: {}, - }; - - if ( - style === config.nativeWindRootPath && - projectType && - projectType !== 'library' - ) { - additionalDependencies = { - dependencies: projectBasedDependencies[projectType].dependencies, - devDependencies: - projectBasedDependencies[projectType]?.devDependencies || {}, - }; - } - additionalDependencies = { dependencies: {}, devDependencies: {} }; - return additionalDependencies; - } catch (error) { - log.error(`\x1b[31mError: ${(error as Error).message}\x1b[0m`); - } -} - //regex check for --path input function isValidPath(path: string): boolean { const pathRegex = /^(?!\/{2})[a-zA-Z/.]{1,2}.*/; @@ -529,7 +498,6 @@ async function ensureFilesPromise(filePaths: string[]): Promise { export { cloneRepositoryAtRoot, getAllComponents, - getAdditionalDependencies, detectProjectType, isValidPath, checkWritablePath, diff --git a/packages/gluestack-cli/src/util/init/index.ts b/packages/gluestack-cli/src/util/init/index.ts index c14b5f89..dda2ed23 100644 --- a/packages/gluestack-cli/src/util/init/index.ts +++ b/packages/gluestack-cli/src/util/init/index.ts @@ -11,11 +11,8 @@ import { generateMonoRepoConfig, getEntryPathAndComponentsPath, } from '../config'; -import { - cloneRepositoryAtRoot, - getAdditionalDependencies, - installDependencies, -} from '..'; +import { cloneRepositoryAtRoot, installDependencies } from '..'; +import { getProjectBasedDependencies } from '../../dependencies'; import { generateConfigNextApp } from '../config/next-config-helper'; import { generateConfigExpoApp } from '../config/expo-config-helper'; import { generateConfigRNApp } from '../config/react-native-config-helper'; @@ -55,7 +52,7 @@ const InitializeGlueStack = async ({ console.log(`\n\x1b[1mInitializing gluestack-ui v2...\x1b[0m\n`); await cloneRepositoryAtRoot(join(_homeDir, config.gluestackDir)); const inputComponent = [config.providerComponent]; - const additionalDependencies = await getAdditionalDependencies( + const additionalDependencies = await getProjectBasedDependencies( projectType, config.style ); From 18c09acb1f86d6c953c9985e2412bd25a21fe232 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Fri, 4 Oct 2024 12:34:28 +0530 Subject: [PATCH 37/71] v0.7.10-alpha.0.9 --- packages/gluestack-cli/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gluestack-cli/package.json b/packages/gluestack-cli/package.json index 7f882829..4ab670ab 100644 --- a/packages/gluestack-cli/package.json +++ b/packages/gluestack-cli/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for easily adding components from gluestack to your projects.", - "version": "0.7.10-alpha.0.8", + "version": "0.7.10-alpha.0.9", "license": "MIT", "main": "dist/index.js", "files": [ From af1c9d1880c113e6ae839b95b47ce975487b6f9e Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Fri, 4 Oct 2024 12:58:14 +0530 Subject: [PATCH 38/71] v2.0.1-alpha.1.3 --- packages/gluestack/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gluestack/package.json b/packages/gluestack/package.json index 29392ab3..3f7eb624 100644 --- a/packages/gluestack/package.json +++ b/packages/gluestack/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for working with gluestack", - "version": "2.0.1-alpha.1.2", + "version": "2.0.1-alpha.1.3", "license": "MIT", "main": "./dist/index.js", "bin": "./dist/index.js", From 0dc0242051ead58e58babcbe447600a1189e4f7c Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Fri, 4 Oct 2024 16:37:51 +0530 Subject: [PATCH 39/71] v2.0.1-alpha.1.5 --- packages/gluestack/package.json | 2 +- packages/gluestack/src/v2.ts | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/gluestack/package.json b/packages/gluestack/package.json index 3f7eb624..b450073b 100644 --- a/packages/gluestack/package.json +++ b/packages/gluestack/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for working with gluestack", - "version": "2.0.1-alpha.1.3", + "version": "2.0.1-alpha.1.5", "license": "MIT", "main": "./dist/index.js", "bin": "./dist/index.js", diff --git a/packages/gluestack/src/v2.ts b/packages/gluestack/src/v2.ts index f2fbb210..74d2b942 100644 --- a/packages/gluestack/src/v2.ts +++ b/packages/gluestack/src/v2.ts @@ -2,13 +2,15 @@ import path from 'path'; import { cancel, text, select, log, spinner } from '@clack/prompts'; import chalk from 'chalk'; -import { execSync } from 'child_process'; +import { promisify } from 'util'; +import { exec, execSync } from 'child_process'; import { displayHelp } from './help'; import templatesMap from './data.js'; const { gitRepo, tag, options } = templatesMap; type RouterType = 'legacy' | 'latest'; type PackageManager = 'npm' | 'yarn' | 'pnpm' | 'bun'; +const execPromise = promisify(exec); interface ProjectOptions { projectType: string; @@ -52,13 +54,13 @@ async function createProject(createOptions: ProjectOptions) { createCommand = `npx @react-native-community/cli@latest init ${projectName} --pm ${packageManager}`; } + const s = spinner(); + s.start(`⏳ Initializing project. This might take a couple of minutes...`); try { - const s = spinner(); - s.start('⏳ Initializing project. This might take a couple of minutes...'); - execSync(createCommand); + await execPromise(createCommand); s.stop(chalk.bold(`✅ Your project is ready!`)); } catch (e) { - console.error(`Failed to create project: ${e}`); + s.stop(chalk.bold(`❌ An error occurred: ${e}`)); throw e; } } From ecf37a2ec56905e93b76b1b2741ea336e822d91f Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Fri, 4 Oct 2024 16:51:36 +0530 Subject: [PATCH 40/71] v2.0.1-alpha.1.6 --- packages/gluestack/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gluestack/package.json b/packages/gluestack/package.json index b450073b..7bc0e366 100644 --- a/packages/gluestack/package.json +++ b/packages/gluestack/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for working with gluestack", - "version": "2.0.1-alpha.1.5", + "version": "2.0.1-alpha.1.6", "license": "MIT", "main": "./dist/index.js", "bin": "./dist/index.js", From 2654b3624f7a378346653db89276470ae5dcd5c6 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Fri, 4 Oct 2024 17:11:21 +0530 Subject: [PATCH 41/71] v2.0.1-alpha.1.7 --- packages/gluestack/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gluestack/package.json b/packages/gluestack/package.json index 7bc0e366..eff3d2ae 100644 --- a/packages/gluestack/package.json +++ b/packages/gluestack/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for working with gluestack", - "version": "2.0.1-alpha.1.6", + "version": "2.0.1-alpha.1.7", "license": "MIT", "main": "./dist/index.js", "bin": "./dist/index.js", From 44f17e6a3646f72a74b4ecc8c93483acf54e6d1f Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Fri, 4 Oct 2024 17:13:22 +0530 Subject: [PATCH 42/71] v2.0.1-alpha.1.8 --- packages/gluestack/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gluestack/package.json b/packages/gluestack/package.json index eff3d2ae..b26d87e1 100644 --- a/packages/gluestack/package.json +++ b/packages/gluestack/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for working with gluestack", - "version": "2.0.1-alpha.1.7", + "version": "2.0.1-alpha.1.8", "license": "MIT", "main": "./dist/index.js", "bin": "./dist/index.js", From b17fa5d25e0dece16a7d4f1670ae98339b509f9a Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Fri, 4 Oct 2024 17:47:15 +0530 Subject: [PATCH 43/71] v2.0.1-alpha.1.9 --- packages/gluestack/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gluestack/package.json b/packages/gluestack/package.json index b26d87e1..53317001 100644 --- a/packages/gluestack/package.json +++ b/packages/gluestack/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for working with gluestack", - "version": "2.0.1-alpha.1.8", + "version": "2.0.1-alpha.1.9", "license": "MIT", "main": "./dist/index.js", "bin": "./dist/index.js", From 94510e44cb04f20291f05528b9d09516b2cd357e Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Fri, 4 Oct 2024 17:50:42 +0530 Subject: [PATCH 44/71] v2.0.1-alpha.2.0 --- packages/gluestack/package.json | 2 +- packages/gluestack/src/data.js | 15 ++++++++++++++ packages/gluestack/src/v2.ts | 36 ++++++++++++++++++++++++++++----- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/packages/gluestack/package.json b/packages/gluestack/package.json index 53317001..53b565e7 100644 --- a/packages/gluestack/package.json +++ b/packages/gluestack/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for working with gluestack", - "version": "2.0.1-alpha.1.9", + "version": "2.0.1-alpha.2.0", "license": "MIT", "main": "./dist/index.js", "bin": "./dist/index.js", diff --git a/packages/gluestack/src/data.js b/packages/gluestack/src/data.js index b798c5e9..a8f37392 100644 --- a/packages/gluestack/src/data.js +++ b/packages/gluestack/src/data.js @@ -48,6 +48,21 @@ module.exports = { ], }, }, + cocoaPods: { + question: 'Would you like to use \x1b[36mCocoaPods\x1b[0m?', + options: [ + { + value: 'react-native-cli-cocoapods', + label: 'Yes', + hint: 'Only needed if you run your project in Xcode directly', + }, + { + value: 'react-native-cli', + label: 'No', + hint: 'For Android or no iOS.', + }, + ], + }, }, style: { bundle: { diff --git a/packages/gluestack/src/v2.ts b/packages/gluestack/src/v2.ts index 74d2b942..3e0d6d97 100644 --- a/packages/gluestack/src/v2.ts +++ b/packages/gluestack/src/v2.ts @@ -2,6 +2,7 @@ import path from 'path'; import { cancel, text, select, log, spinner } from '@clack/prompts'; import chalk from 'chalk'; +import fs from 'fs'; import { promisify } from 'util'; import { exec, execSync } from 'child_process'; import { displayHelp } from './help'; @@ -21,10 +22,20 @@ interface ProjectOptions { async function createProject(createOptions: ProjectOptions) { const { projectName, projectType, packageManager, router } = createOptions; + // Get the absolute path of the folder + const projectPath = path.join(process.cwd(), projectName); + + // Check if the folder exists + if (fs.existsSync(projectPath)) { + throw new Error( + `The folder '${projectName}' already exists in the current directory.` + ); + } let createCommand = ''; + let message = ''; if (projectType.includes('expo')) { // create expo project - + message = `⏳ Creating a new Expo project. Hang tight, this may take a bit...`; const templateFlag = router.includes('expo-router') ? `` : `--template blank-typescript`; @@ -45,17 +56,21 @@ async function createProject(createOptions: ProjectOptions) { } } else if (projectType.includes('nextjs')) { // create next project - + message = `⏳ Creating a new NextJs project. Hang tight, this may take a bit...`; createCommand = projectType.includes('next-page-router') ? `npx create-next-app@latest ${projectName} --ts --no-eslint --use-${packageManager} --import-alias "@/*" --no-tailwind --no-src-dir --no-app` : `npx create-next-app@latest ${projectName} --ts --no-eslint --use-${packageManager} --import-alias "@/*" --no-tailwind --no-src-dir --app`; } else if (projectType.includes('react-native')) { // create react-native project - - createCommand = `npx @react-native-community/cli@latest init ${projectName} --pm ${packageManager}`; + const useCocoapods = router.includes('react-native-cli-cocoapods') + ? true + : false; + createCommand = `npx @react-native-community/cli@latest init ${projectName} --pm ${packageManager} --install-pods ${useCocoapods}`; } const s = spinner(); - s.start(`⏳ Initializing project. This might take a couple of minutes...`); + s.start( + `⏳ Creating a react-native-cli project. Hang tight, this may take a bit...` + ); try { await execPromise(createCommand); s.stop(chalk.bold(`✅ Your project is ready!`)); @@ -162,6 +177,17 @@ export async function main(args: string[]) { }); templateName = selectedRouter; } + if (selectedFramework === 'react-native-cli') { + const { question, options: optionsType } = + // @ts-ignore + options.framework.cocoaPods; + // @ts-ignore + selectedRouter = await select({ + message: question, + options: [...optionsType], + }); + templateName = selectedRouter; + } } if (projName === '') { From db9c7b660d94d7633e644e4768bf19a26a6b42cc Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Fri, 4 Oct 2024 18:04:26 +0530 Subject: [PATCH 45/71] fix: test fixes --- packages/gluestack/src/v2.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/gluestack/src/v2.ts b/packages/gluestack/src/v2.ts index 3e0d6d97..759cf035 100644 --- a/packages/gluestack/src/v2.ts +++ b/packages/gluestack/src/v2.ts @@ -68,9 +68,7 @@ async function createProject(createOptions: ProjectOptions) { createCommand = `npx @react-native-community/cli@latest init ${projectName} --pm ${packageManager} --install-pods ${useCocoapods}`; } const s = spinner(); - s.start( - `⏳ Creating a react-native-cli project. Hang tight, this may take a bit...` - ); + s.start(message); try { await execPromise(createCommand); s.stop(chalk.bold(`✅ Your project is ready!`)); @@ -248,8 +246,9 @@ export async function main(args: string[]) { await createProject(createOptions); await initializeGluestack(createOptions); console.log('done ...'); - } catch { + } catch (e) { console.error('Failed to create project'); + console.error(e); process.exit(1); } } From c83c237ae59f1658ccdded43b5c6ad13b261e66e Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Fri, 4 Oct 2024 19:40:08 +0530 Subject: [PATCH 46/71] feat: add multiple components --- packages/gluestack-cli/src/commands/add.ts | 41 ++--- packages/gluestack-cli/src/util/add/index.ts | 151 +++++++++++-------- packages/gluestack/src/v2.ts | 1 + 3 files changed, 105 insertions(+), 88 deletions(-) diff --git a/packages/gluestack-cli/src/commands/add.ts b/packages/gluestack-cli/src/commands/add.ts index e551d954..b2fa335b 100644 --- a/packages/gluestack-cli/src/commands/add.ts +++ b/packages/gluestack-cli/src/commands/add.ts @@ -4,7 +4,7 @@ import os from 'os'; import { join } from 'path'; import { handleError } from '../util/handle-error'; import { log } from '@clack/prompts'; -import { componentAdder, hookAdder, isHookFromConfig } from '../util/add'; +import { componentAdder } from '../util/add'; import { config } from '../config'; import { checkWritablePath, @@ -18,7 +18,7 @@ import { checkIfInitialized, getComponentsPath } from '../util/config'; const _homeDir = os.homedir(); const addOptionsSchema = z.object({ - components: z.string().optional(), + components: z.array(z.string()), all: z.boolean(), useNpm: z.boolean(), useYarn: z.boolean(), @@ -39,19 +39,13 @@ export const add = new Command() .option('--path ', 'path to the components directory') .action(async (components, opts, command) => { try { - if (command.args.length > 1) { - log.error( - '\x1b[31mOnly one component can be provided at a time, please provide the component name you want to add or --all.\x1b[0m' - ); - process.exit(1); - } const options = addOptionsSchema.parse({ - components: components ?? '', + components: command.args.length > 0 ? command.args : [], ...opts, }); if ( - options.all === false && - (options.components === '' || options.components === undefined) + (!options.all && options.components?.length === 0) || + (options.all && options.components?.length > 0) ) { log.error( '\x1b[31mInvalid arguement, please provide the component/hook name you want to add or --all.\x1b[0m' @@ -94,24 +88,15 @@ export const add = new Command() config.writableComponentsPath = options.path; } await cloneRepositoryAtRoot(join(_homeDir, config.gluestackDir)); + // define args based on --all or components + const args = options.all + ? { addAll: true } + : { componentArgs: options.components.map((c) => c.toLowerCase()) }; - if (options.all) { - try { - await componentAdder({ - requestedComponent: '--all', - }); - } catch (err) { - log.error(`\x1b[31mError: ${(err as Error).message}\x1b[0m`); - } - } else if (await isHookFromConfig(options.components)) { - options.components && - (await hookAdder({ - requestedHook: options.components, - })); - } else { - await componentAdder({ - requestedComponent: options.components?.toLowerCase(), - }); + try { + await componentAdder(args); + } catch (err) { + log.error(`\x1b[31mError: ${(err as Error).message}\x1b[0m`); } } catch (err) { handleError(err); diff --git a/packages/gluestack-cli/src/util/add/index.ts b/packages/gluestack-cli/src/util/add/index.ts index 6b0a91ea..5a0741ff 100644 --- a/packages/gluestack-cli/src/util/add/index.ts +++ b/packages/gluestack-cli/src/util/add/index.ts @@ -1,4 +1,5 @@ import fs from 'fs-extra'; +import chalk from 'chalk'; import os from 'os'; import { basename, join, parse } from 'path'; import { log, confirm } from '@clack/prompts'; @@ -15,56 +16,65 @@ const _homeDir = os.homedir(); let existingComponentsChecked: boolean = false; const componentAdder = async ({ - requestedComponent = '', + addAll = false, + componentArgs = [], showWarning = true, +}: { + addAll?: boolean; + componentArgs?: Array; + showWarning?: boolean; }) => { try { - console.log(`\n\x1b[1mAdding new component...\x1b[0m\n`); - let hooksToAdd: string[] = []; - if ( - requestedComponent && - requestedComponent !== '--all' && - !(await checkIfComponentIsValid(requestedComponent)) - ) { - log.error( - `The ${requestedComponent} does not exist. Kindly choose a valid component name.` - ); - return; - } - let requestedComponents = - requestedComponent === '--all' - ? await getAllComponents() - : [requestedComponent]; - - const { hooks } = await checkComponentDependencies(requestedComponents); - hooksToAdd = Array.from(hooks); - - const updatedComponents = - !existingComponentsChecked && showWarning && requestedComponent - ? await isComponentInProject(requestedComponents) - : requestedComponents; - const count = updatedComponents.length; - await Promise.all( - updatedComponents.map(async (component) => { - const targetPath = join( - projectRootPath, - config.writableComponentsPath, - component + const res = await sortComponentsAndHooks(componentArgs); + let componentsToAdd = res.components; + let hooksToAdd = res.hooks; + if (componentsToAdd.length > 0 || addAll) { + if ( + !addAll && + componentsToAdd?.length && + !(await checkIfComponentIsValid(componentsToAdd)) + ) { + log.error( + chalk.red( + `Invalid names entered. Kindly check and choose a valid component name.` + ) ); + return; + } + console.log(`\n\x1b[1mAdding new component...\x1b[0m\n`); + let requestedComponents = addAll + ? await getAllComponents() + : componentsToAdd; + const { hooks } = await checkComponentDependencies(requestedComponents); + hooksToAdd = Array.from(hooks); - await writeComponent(component, targetPath); - }) - ) - .then(async () => { - await installDependencies(updatedComponents); - log.success( - `\x1b[32mDone!\x1b[0m Added new \x1b[1mgluestack-ui\x1b[0m ${count === 1 ? 'component' : 'components'} into project` - ); - }) - .catch((err) => { - log.error(`\x1b[31mError : ${(err as Error).message}\x1b[0m`); - }); - if (hooksToAdd.length > 0) await hookAdder({ requestedHook: hooksToAdd }); + const updatedComponents = + !existingComponentsChecked && showWarning && componentsToAdd.length + ? await isComponentInProject(requestedComponents) + : requestedComponents; + const count = updatedComponents.length; + await Promise.all( + updatedComponents.map(async (component) => { + const targetPath = join( + projectRootPath, + config.writableComponentsPath, + component + ); + + await writeComponent(component, targetPath); + }) + ) + .then(async () => { + await installDependencies(updatedComponents); + log.success( + `\x1b[32mDone!\x1b[0m Added new \x1b[1mgluestack-ui\x1b[0m ${count === 1 ? 'component' : 'components'} into project` + ); + }) + .catch((err) => { + log.error(`\x1b[31mError : ${(err as Error).message}\x1b[0m`); + }); + } + if (hooksToAdd.length > 0) await hookAdder(hooksToAdd); } catch (err) { log.error(`\x1b[31mError: ${(err as Error).message}\x1b[0m`); } @@ -121,9 +131,11 @@ const processTerminate = (message: string) => { process.exit(1); }; -const checkIfComponentIsValid = async (component: string): Promise => { +const checkIfComponentIsValid = async ( + components: string[] +): Promise => { const componentList = await getAllComponents(); - if (componentList.includes(component) || componentList.includes(component)) + if (components.every((component) => componentList.includes(component))) return true; else return false; }; @@ -165,11 +177,7 @@ const confirmOverride = async ( return shouldContinue; }; -const hookAdder = async ({ - requestedHook, -}: { - requestedHook: string | string[]; -}) => { +const hookAdder = async (requestedHook: string[]) => { try { console.log(`\n\x1b[1mAdding new hook...\x1b[0m\n`); await writeHook(requestedHook); @@ -181,12 +189,36 @@ const hookAdder = async ({ } }; -const isHookFromConfig = async (hook: string | undefined): Promise => { +const sortComponentsAndHooks = async ( + inputNames: string[] | undefined +): Promise<{ hooks: string[]; components: string[] }> => { + if (!inputNames || inputNames.length === 0) { + return { hooks: [], components: [] }; + } + + const hooksPath = join( + _homeDir, + config.gluestackDir, + config.hooksResourcePath + ); const hooksList = fs - .readdirSync(join(_homeDir, config.gluestackDir, config.hooksResourcePath)) - .map((file) => removeHyphen(parse(file).name)); - if (hook && hooksList.includes(hook.toLowerCase())) return true; - else return false; + .readdirSync(hooksPath) + .map((file) => removeHyphen(parse(file).name).toLowerCase()); + + const result = inputNames.reduce( + (acc, name) => { + const lowercaseName = name.toLowerCase(); + if (hooksList.includes(lowercaseName)) { + acc.hooks.push(name); + } else { + acc.components.push(name); + } + return acc; + }, + { hooks: [] as string[], components: [] as string[] } + ); + + return result; }; const hookFileName = async (hook: string): Promise => { @@ -201,8 +233,7 @@ const hookFileName = async (hook: string): Promise => { }); return fileName; }; -const writeHook = async (hooks: string | string[]) => { - const hooksArray = Array.isArray(hooks) ? hooks : [hooks]; +const writeHook = async (hooksArray: string[]) => { for (const hook of hooksArray) { const fileName = await hookFileName(hook); const utilsPath = join( @@ -243,4 +274,4 @@ const confirmHookOverride = async (hook: string): Promise => { return shouldContinue; }; -export { componentAdder, getAllComponents, isHookFromConfig, hookAdder }; +export { componentAdder, getAllComponents }; diff --git a/packages/gluestack/src/v2.ts b/packages/gluestack/src/v2.ts index 759cf035..e2e4061e 100644 --- a/packages/gluestack/src/v2.ts +++ b/packages/gluestack/src/v2.ts @@ -62,6 +62,7 @@ async function createProject(createOptions: ProjectOptions) { : `npx create-next-app@latest ${projectName} --ts --no-eslint --use-${packageManager} --import-alias "@/*" --no-tailwind --no-src-dir --app`; } else if (projectType.includes('react-native')) { // create react-native project + message = `⏳ Creating a react-native-cli project. Hang tight, this may take a bit...`; const useCocoapods = router.includes('react-native-cli-cocoapods') ? true : false; From d082c40db421bbb088de1271eba7c00dc074d74a Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Fri, 4 Oct 2024 19:40:48 +0530 Subject: [PATCH 47/71] v2.0.1-alpha.2.1 --- packages/gluestack/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gluestack/package.json b/packages/gluestack/package.json index 53b565e7..061cb66d 100644 --- a/packages/gluestack/package.json +++ b/packages/gluestack/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for working with gluestack", - "version": "2.0.1-alpha.2.0", + "version": "2.0.1-alpha.2.1", "license": "MIT", "main": "./dist/index.js", "bin": "./dist/index.js", From fbdb310bf432bc9880ac115d69729621857cb152 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Mon, 7 Oct 2024 17:59:44 +0530 Subject: [PATCH 48/71] v0.7.10-alpha.1.0 --- packages/gluestack-cli/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gluestack-cli/package.json b/packages/gluestack-cli/package.json index 4ab670ab..862856d7 100644 --- a/packages/gluestack-cli/package.json +++ b/packages/gluestack-cli/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for easily adding components from gluestack to your projects.", - "version": "0.7.10-alpha.0.9", + "version": "0.7.10-alpha.1.0", "license": "MIT", "main": "dist/index.js", "files": [ From 66207c3a9173b9a34ba114e8daa24617c8d069cc Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Thu, 17 Oct 2024 15:01:07 +0530 Subject: [PATCH 49/71] feat: added templateFlag to add --- packages/gluestack-cli/src/commands/add.ts | 12 +++++++++++- packages/gluestack-cli/src/commands/init.ts | 1 + packages/gluestack-cli/src/index.ts | 1 - packages/gluestack-cli/src/util/add/index.ts | 4 +--- packages/gluestack/src/v2.ts | 2 +- 5 files changed, 14 insertions(+), 6 deletions(-) diff --git a/packages/gluestack-cli/src/commands/add.ts b/packages/gluestack-cli/src/commands/add.ts index b2fa335b..fdebdb0d 100644 --- a/packages/gluestack-cli/src/commands/add.ts +++ b/packages/gluestack-cli/src/commands/add.ts @@ -25,6 +25,7 @@ const addOptionsSchema = z.object({ usePnpm: z.boolean(), useBun: z.boolean(), path: z.string().optional(), + templateOnly: z.boolean(), }); export const add = new Command() @@ -37,12 +38,20 @@ export const add = new Command() .option('--use-pnpm, usePnpm', 'use pnpm to install dependencies', false) .option('--use-bun, useBun', 'use bun to install dependencies', false) .option('--path ', 'path to the components directory') + .option( + '--template-only templateOnly', + 'Only install the template without installing dependencies', + false + ) .action(async (components, opts, command) => { try { const options = addOptionsSchema.parse({ components: command.args.length > 0 ? command.args : [], ...opts, }); + const isTemplate = options.templateOnly; + !isTemplate && console.log('\n\x1b[1mWelcome to gluestack-ui!\x1b[0m\n'); + if ( (!options.all && options.components?.length === 0) || (options.all && options.components?.length > 0) @@ -87,7 +96,8 @@ export const add = new Command() await checkWritablePath(options.path); config.writableComponentsPath = options.path; } - await cloneRepositoryAtRoot(join(_homeDir, config.gluestackDir)); + !isTemplate && + (await cloneRepositoryAtRoot(join(_homeDir, config.gluestackDir))); // define args based on --all or components const args = options.all ? { addAll: true } diff --git a/packages/gluestack-cli/src/commands/init.ts b/packages/gluestack-cli/src/commands/init.ts index 11fd79fc..1c1febcf 100644 --- a/packages/gluestack-cli/src/commands/init.ts +++ b/packages/gluestack-cli/src/commands/init.ts @@ -48,6 +48,7 @@ export const init = new Command() try { const options = initOptionsSchema.parse({ ...opts }); const isTemplate = options.templateOnly; + console.log('\n\x1b[1mWelcome to gluestack-ui!\x1b[0m\n'); const cwd = process.cwd(); //if cwd doesn't have package.json file if (!fs.existsSync(path.join(cwd, 'package.json'))) { diff --git a/packages/gluestack-cli/src/index.ts b/packages/gluestack-cli/src/index.ts index 89b0456b..f4ff9890 100644 --- a/packages/gluestack-cli/src/index.ts +++ b/packages/gluestack-cli/src/index.ts @@ -16,7 +16,6 @@ process.on('SIGTERM', () => { async function main() { const program = new Command().name('gluestack-ui'); - console.log('\n\x1b[1mWelcome to gluestack-ui!\x1b[0m\n'); // Define action for unrecognized commands program.action(() => { log.error( diff --git a/packages/gluestack-cli/src/util/add/index.ts b/packages/gluestack-cli/src/util/add/index.ts index 5a0741ff..c089cf96 100644 --- a/packages/gluestack-cli/src/util/add/index.ts +++ b/packages/gluestack-cli/src/util/add/index.ts @@ -18,11 +18,9 @@ let existingComponentsChecked: boolean = false; const componentAdder = async ({ addAll = false, componentArgs = [], - showWarning = true, }: { addAll?: boolean; componentArgs?: Array; - showWarning?: boolean; }) => { try { const res = await sortComponentsAndHooks(componentArgs); @@ -49,7 +47,7 @@ const componentAdder = async ({ hooksToAdd = Array.from(hooks); const updatedComponents = - !existingComponentsChecked && showWarning && componentsToAdd.length + !existingComponentsChecked && requestedComponents.length ? await isComponentInProject(requestedComponents) : requestedComponents; const count = updatedComponents.length; diff --git a/packages/gluestack/src/v2.ts b/packages/gluestack/src/v2.ts index e2e4061e..fd39ea50 100644 --- a/packages/gluestack/src/v2.ts +++ b/packages/gluestack/src/v2.ts @@ -87,7 +87,7 @@ async function initializeGluestack(projectOptions: ProjectOptions) { `npx gluestack-ui@alpha init --template-only --projectType ${projectType} --use-${packageManager}`, { stdio: 'inherit' } ); - execSync(`npx gluestack-ui@alpha add --all`, { + execSync(`npx gluestack-ui@alpha add --all --template-only`, { stdio: 'inherit', }); } catch (e) { From 7166b64b3fb96ce7cb0bf8b857b14f7cc5c8b325 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Tue, 22 Oct 2024 11:39:32 +0530 Subject: [PATCH 50/71] feat: windows support --- .../src/util/config/expo-config-helper.ts | 39 +++++++++++-------- .../src/util/config/next-config-helper.ts | 36 +++++++++++------ .../util/config/react-native-config-helper.ts | 34 +++++++++------- packages/gluestack-cli/src/util/index.ts | 11 ++++-- .../codemods/expo/babel-config-transform.ts | 6 +-- .../codemods/expo/metro-config-transform.ts | 5 +-- 6 files changed, 78 insertions(+), 53 deletions(-) diff --git a/packages/gluestack-cli/src/util/config/expo-config-helper.ts b/packages/gluestack-cli/src/util/config/expo-config-helper.ts index 87b20d6c..cb312b64 100644 --- a/packages/gluestack-cli/src/util/config/expo-config-helper.ts +++ b/packages/gluestack-cli/src/util/config/expo-config-helper.ts @@ -68,22 +68,28 @@ async function isExpoSDK50(cwd: string): Promise { async function resolvedExpoPaths(resultConfig: ExpoResolvedConfig) { const resolvedExpoPaths = { tailwind: { - config: path.resolve(_currDir, resultConfig.tailwind.config), - css: path.resolve(_currDir, resultConfig.tailwind.css), + config: path + .resolve(_currDir, resultConfig.tailwind.config) + .replace(/\\/g, '/'), + css: path + .resolve(_currDir, resultConfig.tailwind.css) + .replace(/\\/g, '/'), }, config: { - babelConfig: path.resolve( - _currDir, - resultConfig.config.babelConfig || '' - ), - metroConfig: path.resolve( - _currDir, - resultConfig.config.metroConfig || '' - ), - tsConfig: path.resolve(_currDir, resultConfig.config.tsConfig || ''), + babelConfig: path + .resolve(_currDir, resultConfig.config.babelConfig || '') + .replace(/\\/g, '/'), + metroConfig: path + .resolve(_currDir, resultConfig.config.metroConfig || '') + .replace(/\\/g, '/'), + tsConfig: path + .resolve(_currDir, resultConfig.config.tsConfig || '') + .replace(/\\/g, '/'), }, app: { - entry: path.resolve(_currDir, resultConfig.app.entry || ''), + entry: path + .resolve(_currDir, resultConfig.app.entry || '') + .replace(/\\/g, '/'), type: resultConfig?.app?.type, sdk50: resultConfig?.app?.sdk50, }, @@ -118,16 +124,17 @@ async function initNatiwindExpoApp( expoTransformer, 'expo-add-provider-transform.ts' ); + execSync( `npx jscodeshift -t ${metroTransformerPath} ${ resolvedConfig.config.metroConfig - } --cssPath='${cssPath}' --config='${JSON.stringify(resolvedConfig)}'` + } --cssPath=${cssPath} --isSDK50=${resolvedConfig.app.sdk50}` ); execSync( - `npx jscodeshift -t ${BabeltransformerPath} ${resolvedConfig.config.babelConfig} --config='${JSON.stringify(resolvedConfig)}'` + `npx jscodeshift -t ${BabeltransformerPath} ${resolvedConfig.config.babelConfig} --isSDK50=${resolvedConfig.app.sdk50} --tailwindConfig=${resolvedConfig.tailwind.config}` ); execSync( - `npx jscodeshift -t ${addProviderTransformerPath} ${resolvedConfig.app.entry} --cssImportPath='${cssImportPath}' --componentsPath='${config.writableComponentsPath}'` + `npx jscodeshift -t ${addProviderTransformerPath} ${resolvedConfig.app.entry} --cssImportPath=${cssImportPath} --componentsPath=${config.writableComponentsPath}` ); execSync('npx expo install babel-plugin-module-resolver', { stdio: 'inherit', @@ -188,7 +195,7 @@ async function generateConfigExpoApp(permission: boolean) { resolvedConfig.config.metroConfig, resolvedConfig.config.tsConfig, resolvedConfig.tailwind.css, - join(_currDir, 'nativewind-env.d.ts'), + join(_currDir, 'nativewind-env.d.ts').replace(/\\/g, '/'), ]; const filesEnsured = await ensureFilesPromise(filesTobeEnsured); if (permission && filesEnsured) { diff --git a/packages/gluestack-cli/src/util/config/next-config-helper.ts b/packages/gluestack-cli/src/util/config/next-config-helper.ts index feef2ef1..d42043a8 100644 --- a/packages/gluestack-cli/src/util/config/next-config-helper.ts +++ b/packages/gluestack-cli/src/util/config/next-config-helper.ts @@ -43,21 +43,32 @@ async function getNextProjectType(cwd: string): Promise { async function resolvedNextJsPaths(resultConfig: NextResolvedConfig) { const resolvedNextJsPaths = { tailwind: { - config: path.resolve(_currDir, resultConfig.tailwind.config), - css: path.resolve(_currDir, resultConfig.tailwind.css), + config: path + .resolve(_currDir, resultConfig.tailwind.config) + .replace(/\\/g, '/'), + css: path + .resolve(_currDir, resultConfig.tailwind.css) + .replace(/\\/g, '/'), }, config: { - postCssConfig: path.resolve( - _currDir, - resultConfig.config.postCssConfig || '' - ), - nextConfig: path.resolve(_currDir, resultConfig.config.nextConfig || ''), - tsConfig: path.resolve(_currDir, resultConfig.config.tsConfig || ''), + postCssConfig: path + .resolve(_currDir, resultConfig.config.postCssConfig || '') + .replace(/\\/g, '/'), + nextConfig: path + .resolve(_currDir, resultConfig.config.nextConfig || '') + .replace(/\\/g, '/'), + tsConfig: path + .resolve(_currDir, resultConfig.config.tsConfig || '') + .replace(/\\/g, '/'), }, app: { - entry: path.resolve(_currDir, resultConfig.app.entry || ''), + entry: path + .resolve(_currDir, resultConfig.app.entry || '') + .replace(/\\/g, '/'), type: resultConfig?.app?.type, - registry: resultConfig?.app?.registry, + registry: resultConfig?.app?.registry + ? resultConfig.app.registry.replace(/\\/g, '/') + : undefined, }, }; return resolvedNextJsPaths; @@ -143,7 +154,7 @@ async function generateConfigNextApp(permission: boolean) { let registryPath = ''; if (projectType?.includes('app')) { const appDirectory = findDirectory(_currDir, ['src/app', 'app']); - registryPath = path.join(_currDir, appDirectory, 'registry.tsx'); + registryPath = path.resolve(_currDir, appDirectory, 'registry.tsx'); } const gluestackConfig: RawConfig = { @@ -186,7 +197,8 @@ async function generateConfigNextApp(permission: boolean) { resolvedConfig.app.registry ?? '', resolvedConfig.config.tsConfig, resolvedConfig.tailwind.css, - join(_currDir, 'nativewind-env.d.ts'), + resolvedConfig.config.postCssConfig, + path.resolve(_currDir, 'nativewind-env.d.ts').replace(/\\/g, '/'), ]; const filesEnsured = await ensureFilesPromise(filesTobeEnsured); if (permission && filesEnsured) { diff --git a/packages/gluestack-cli/src/util/config/react-native-config-helper.ts b/packages/gluestack-cli/src/util/config/react-native-config-helper.ts index 86218bad..a7cb0b77 100644 --- a/packages/gluestack-cli/src/util/config/react-native-config-helper.ts +++ b/packages/gluestack-cli/src/util/config/react-native-config-helper.ts @@ -16,22 +16,28 @@ async function resolvedReactNativePaths( ) { const resolvedReactNativePaths = { tailwind: { - config: path.resolve(_currDir, resultConfig.tailwind.config), - css: path.resolve(_currDir, resultConfig.tailwind.css), + config: path + .resolve(_currDir, resultConfig.tailwind.config) + .replace(/\\/g, '/'), + css: path + .resolve(_currDir, resultConfig.tailwind.css) + .replace(/\\/g, '/'), }, config: { - babelConfig: path.resolve( - _currDir, - resultConfig.config.babelConfig || '' - ), - metroConfig: path.resolve( - _currDir, - resultConfig.config.metroConfig || '' - ), - tsConfig: path.resolve(_currDir, resultConfig.config.tsConfig || ''), + babelConfig: path + .resolve(_currDir, resultConfig.config.babelConfig || '') + .replace(/\\/g, '/'), + metroConfig: path + .resolve(_currDir, resultConfig.config.metroConfig || '') + .replace(/\\/g, '/'), + tsConfig: path + .resolve(_currDir, resultConfig.config.tsConfig || '') + .replace(/\\/g, '/'), }, app: { - entry: path.resolve(_currDir, resultConfig.app.entry || ''), + entry: path + .resolve(_currDir, resultConfig.app.entry || '') + .replace(/\\/g, '/'), }, }; return resolvedReactNativePaths; @@ -106,7 +112,7 @@ async function generateConfigRNApp(permission: boolean) { }, app: { entry: entryPath, - components: 'components/ui', + components: config.writableComponentsPath, }, }; const resolvedGluestackConfig = { @@ -122,7 +128,7 @@ async function generateConfigRNApp(permission: boolean) { tsConfig: tsConfigPath.length ? tsConfigPath : 'tsconfig.json', }, app: { - entry: path.resolve(_currDir, entryPath), + entry: path.resolve(_currDir, entryPath).replace(/\\/g, '/'), }, }; diff --git a/packages/gluestack-cli/src/util/index.ts b/packages/gluestack-cli/src/util/index.ts index 3c73293c..3f22a255 100644 --- a/packages/gluestack-cli/src/util/index.ts +++ b/packages/gluestack-cli/src/util/index.ts @@ -100,10 +100,7 @@ const cloneRepositoryAtRoot = async (rootPath: string) => { await pullComponentRepo(join(homeDir, config.gluestackDir)); } } else { - const s = spinner(); - s.start('Cloning repository...'); await cloneComponentRepo(rootPath, config.repoUrl); - s.stop('Repository cloned successfully.'); } } catch (err) { log.error(`\x1b[31m Cloning failed, ${(err as Error).message}\x1b[0m`); @@ -487,7 +484,13 @@ async function ensureFilesPromise(filePaths: string[]): Promise { (path) => path && typeof path === 'string' && path.trim() !== '' ); // Use Promise.all to run all ensureFile operations concurrently - await Promise.all(validPaths.map((path) => fs.ensureFile(path))); + await Promise.all( + validPaths.map(async (filePath) => { + // Normalize the path and ensure the file + const normalizedPath = filePath.normalize(); + await fs.ensureFile(normalizedPath); // Ensure the file exists asynchronously + }) + ); return true; // All operations successful } catch (error) { console.error('Error ensuring files:', error); diff --git a/packages/gluestack-cli/template/codemods/expo/babel-config-transform.ts b/packages/gluestack-cli/template/codemods/expo/babel-config-transform.ts index 6b923279..7bf7fe94 100644 --- a/packages/gluestack-cli/template/codemods/expo/babel-config-transform.ts +++ b/packages/gluestack-cli/template/codemods/expo/babel-config-transform.ts @@ -4,15 +4,13 @@ import { ObjectExpression, Property, } from 'jscodeshift'; -import { ExpoResolvedConfig } from '../../../src/util/config/config-types'; const transform: Transform = (file, api, options): string => { try { const j = api.jscodeshift; const root = j(file.source); - const config: ExpoResolvedConfig = options.config; - const isSDK50 = config.app.sdk50; - const tailwindConfig = config.tailwind.config; + const isSDK50 = options.isSDK50; + const tailwindConfig = options.tailwindConfig; root.find(j.ReturnStatement).forEach((path) => { const returnObject = path.node.argument as ObjectExpression | null; diff --git a/packages/gluestack-cli/template/codemods/expo/metro-config-transform.ts b/packages/gluestack-cli/template/codemods/expo/metro-config-transform.ts index e470bea3..1afa61d6 100644 --- a/packages/gluestack-cli/template/codemods/expo/metro-config-transform.ts +++ b/packages/gluestack-cli/template/codemods/expo/metro-config-transform.ts @@ -8,8 +8,7 @@ const transform: Transform = (file, api, options) => { const j = api.jscodeshift; const source = file.source.trim(); const cssPath = options.cssPath; - const config: ExpoResolvedConfig = options.config; - const isSDK50 = config.app.sdk50; + const isSDK50 = options.isSDK50; if (source.length === 0) { const metroConfigContent = isSDK50 ? `const { getDefaultConfig } = require('expo/metro-config'); @@ -28,7 +27,7 @@ module.exports = withNativeWind(config, { input: '${cssPath}' });`; const ast = parse(metroConfigContent); // Print the AST back to code const output = print(ast).code; - writeFileSync(config.config.metroConfig, output, 'utf8'); + writeFileSync(file.path, output, 'utf8'); return null; // Return early after writing the file } const root = j(source); From ed2550881c12b67e73e915ca0631e6343653fc6e Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Tue, 22 Oct 2024 11:54:29 +0530 Subject: [PATCH 51/71] v0.7.10-alpha.1.1 --- packages/gluestack-cli/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gluestack-cli/package.json b/packages/gluestack-cli/package.json index 862856d7..2ea3f6d9 100644 --- a/packages/gluestack-cli/package.json +++ b/packages/gluestack-cli/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for easily adding components from gluestack to your projects.", - "version": "0.7.10-alpha.1.0", + "version": "0.7.10-alpha.1.1", "license": "MIT", "main": "dist/index.js", "files": [ From 66122e1f7d9efa3f457acae61472d71f1bcc824a Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Tue, 22 Oct 2024 14:43:18 +0530 Subject: [PATCH 52/71] fix: next initializer --- .../src/util/config/next-config-helper.ts | 10 ++++++---- packages/gluestack-cli/src/util/index.ts | 2 +- packages/gluestack-cli/src/util/init/index.ts | 2 +- .../codemods/nextjs/next-add-provider-transform.ts | 3 +-- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/packages/gluestack-cli/src/util/config/next-config-helper.ts b/packages/gluestack-cli/src/util/config/next-config-helper.ts index d42043a8..4520d877 100644 --- a/packages/gluestack-cli/src/util/config/next-config-helper.ts +++ b/packages/gluestack-cli/src/util/config/next-config-helper.ts @@ -91,7 +91,10 @@ async function initNatiwindNextApp( if (nextConfigPath?.endsWith('.mjs')) { fileType = 'mjs'; - } else if (nextConfigPath?.endsWith('.js')) { + } else if ( + nextConfigPath?.endsWith('.js') || + nextConfigPath?.endsWith('.ts') + ) { fileType = 'js'; } nextTransformerPath = join( @@ -121,14 +124,13 @@ async function initNatiwindNextApp( execSync(`npx jscodeshift -t ${transformerPath} ${docsPagePath}`); } - const options = JSON.stringify(resolvedConfig); const transformerPath = join( - `${NextTransformer}/next-add-provider-transform.ts --config='${options}'` + `${NextTransformer}/next-add-provider-transform.ts` ); const rawCssPath = relative(_currDir, resolvedConfig.tailwind.css); const cssImportPath = '@/'.concat(rawCssPath); execSync( - `npx jscodeshift -t ${transformerPath} ${resolvedConfig.app.entry} --componentsPath='${config.writableComponentsPath}' --cssImportPath='${cssImportPath}'` + `npx jscodeshift -t ${transformerPath} ${resolvedConfig.app.entry} --componentsPath=${config.writableComponentsPath} --cssImportPath=${cssImportPath} ` ); await commonInitialization( config.nextJsProject, diff --git a/packages/gluestack-cli/src/util/index.ts b/packages/gluestack-cli/src/util/index.ts index 3f22a255..56124e3e 100644 --- a/packages/gluestack-cli/src/util/index.ts +++ b/packages/gluestack-cli/src/util/index.ts @@ -337,7 +337,7 @@ const installDependencies = async ( async function detectProjectType(directoryPath: string): Promise { try { const fileChecks: { [key: string]: string[] } = { - nextjs: ['next.config.js', 'next.config.mjs'], + nextjs: ['next.config.js', 'next.config.mjs', 'next.config.ts'], expo: ['app.json', 'app.config.js', 'app.config.ts'], reactNative: ['ios', 'android'], }; diff --git a/packages/gluestack-cli/src/util/init/index.ts b/packages/gluestack-cli/src/util/init/index.ts index dda2ed23..1fea5dc7 100644 --- a/packages/gluestack-cli/src/util/init/index.ts +++ b/packages/gluestack-cli/src/util/init/index.ts @@ -307,7 +307,7 @@ const filesToOverride = (projectType: string) => { switch (projectType) { case config.nextJsProject: return [ - 'next.config(.mjs/.js)', + 'next.config.*', 'tailwind.config.js', 'global.css', 'tsconfig.json', diff --git a/packages/gluestack-cli/template/codemods/nextjs/next-add-provider-transform.ts b/packages/gluestack-cli/template/codemods/nextjs/next-add-provider-transform.ts index 86f0e7fc..3d5c95f0 100644 --- a/packages/gluestack-cli/template/codemods/nextjs/next-add-provider-transform.ts +++ b/packages/gluestack-cli/template/codemods/nextjs/next-add-provider-transform.ts @@ -5,7 +5,6 @@ const transform: Transform = (file, api, options) => { try { const j = api.jscodeshift.withParser('tsx'); const root = j(file.source); - const config: NextResolvedConfig = options.config || {}; const componentsImportPath = options.componentsPath; const cssImportPath = options.cssImportPath; @@ -94,7 +93,7 @@ const transform: Transform = (file, api, options) => { } /* condition to check if StyledJsxRegistry is needed */ - const hasStyledJsx = config.app.entry?.includes('layout') || false; + const hasStyledJsx = file.path?.includes('layout') || false; const bodyElement = root.find(j.JSXElement, { openingElement: { name: { name: 'body' } }, From ef909fd11149762038cbc55ea8df12e3ef4af4e6 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Tue, 22 Oct 2024 14:43:54 +0530 Subject: [PATCH 53/71] v0.7.10-alpha.1.2 --- packages/gluestack-cli/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gluestack-cli/package.json b/packages/gluestack-cli/package.json index 2ea3f6d9..60feea3b 100644 --- a/packages/gluestack-cli/package.json +++ b/packages/gluestack-cli/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for easily adding components from gluestack to your projects.", - "version": "0.7.10-alpha.1.1", + "version": "0.7.10-alpha.1.2", "license": "MIT", "main": "dist/index.js", "files": [ From d9affb8827ec4bd6c76d0cc3d8c25b62059a5046 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Tue, 22 Oct 2024 14:53:41 +0530 Subject: [PATCH 54/71] fix: next initializer --- .../template/codemods/nextjs/next-add-provider-transform.ts | 1 - .../template/codemods/nextjs/next-config-js-transform.ts | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/gluestack-cli/template/codemods/nextjs/next-add-provider-transform.ts b/packages/gluestack-cli/template/codemods/nextjs/next-add-provider-transform.ts index 3d5c95f0..43fb11da 100644 --- a/packages/gluestack-cli/template/codemods/nextjs/next-add-provider-transform.ts +++ b/packages/gluestack-cli/template/codemods/nextjs/next-add-provider-transform.ts @@ -1,5 +1,4 @@ import { Transform } from 'jscodeshift'; -import { NextResolvedConfig } from '../../../src//util/config/config-types'; const transform: Transform = (file, api, options) => { try { diff --git a/packages/gluestack-cli/template/codemods/nextjs/next-config-js-transform.ts b/packages/gluestack-cli/template/codemods/nextjs/next-config-js-transform.ts index 3126cdcf..5ca59c08 100644 --- a/packages/gluestack-cli/template/codemods/nextjs/next-config-js-transform.ts +++ b/packages/gluestack-cli/template/codemods/nextjs/next-config-js-transform.ts @@ -2,7 +2,9 @@ import { Transform } from 'jscodeshift'; const transform: Transform = (file, api) => { try { - const j = api.jscodeshift; + const j = file.path.includes('.ts') + ? api.jscodeshift.withParser('ts') + : api.jscodeshift; const root = j(file.source); // Step 1: Check if the import statement for withGluestackUI already exists From d1fd4bc6ed50c6aa9470f852efff403e32bed2d6 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Tue, 22 Oct 2024 14:54:05 +0530 Subject: [PATCH 55/71] v0.7.10-alpha.1.3 --- packages/gluestack-cli/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gluestack-cli/package.json b/packages/gluestack-cli/package.json index 60feea3b..6df49ffa 100644 --- a/packages/gluestack-cli/package.json +++ b/packages/gluestack-cli/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for easily adding components from gluestack to your projects.", - "version": "0.7.10-alpha.1.2", + "version": "0.7.10-alpha.1.3", "license": "MIT", "main": "dist/index.js", "files": [ From d48ac86b7f1110cc7b402820bbeb78a5931dfa2b Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Tue, 22 Oct 2024 15:52:09 +0530 Subject: [PATCH 56/71] fix: next config typescript --- .../gluestack-cli/src/util/config/next-config-helper.ts | 7 ++----- .../template/codemods/nextjs/next-config-js-transform.ts | 4 +--- .../template/codemods/nextjs/next-config-mjs-transform.ts | 4 +++- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/packages/gluestack-cli/src/util/config/next-config-helper.ts b/packages/gluestack-cli/src/util/config/next-config-helper.ts index 4520d877..c69dc0c2 100644 --- a/packages/gluestack-cli/src/util/config/next-config-helper.ts +++ b/packages/gluestack-cli/src/util/config/next-config-helper.ts @@ -89,12 +89,9 @@ async function initNatiwindNextApp( let nextTransformerPath = ''; let fileType = ''; - if (nextConfigPath?.endsWith('.mjs')) { + if (nextConfigPath?.endsWith('.mjs') || nextConfigPath?.endsWith('.ts')) { fileType = 'mjs'; - } else if ( - nextConfigPath?.endsWith('.js') || - nextConfigPath?.endsWith('.ts') - ) { + } else if (nextConfigPath?.endsWith('.js')) { fileType = 'js'; } nextTransformerPath = join( diff --git a/packages/gluestack-cli/template/codemods/nextjs/next-config-js-transform.ts b/packages/gluestack-cli/template/codemods/nextjs/next-config-js-transform.ts index 5ca59c08..3126cdcf 100644 --- a/packages/gluestack-cli/template/codemods/nextjs/next-config-js-transform.ts +++ b/packages/gluestack-cli/template/codemods/nextjs/next-config-js-transform.ts @@ -2,9 +2,7 @@ import { Transform } from 'jscodeshift'; const transform: Transform = (file, api) => { try { - const j = file.path.includes('.ts') - ? api.jscodeshift.withParser('ts') - : api.jscodeshift; + const j = api.jscodeshift; const root = j(file.source); // Step 1: Check if the import statement for withGluestackUI already exists diff --git a/packages/gluestack-cli/template/codemods/nextjs/next-config-mjs-transform.ts b/packages/gluestack-cli/template/codemods/nextjs/next-config-mjs-transform.ts index 0d5c56c5..ca78dc52 100644 --- a/packages/gluestack-cli/template/codemods/nextjs/next-config-mjs-transform.ts +++ b/packages/gluestack-cli/template/codemods/nextjs/next-config-mjs-transform.ts @@ -7,7 +7,9 @@ import { const transform: Transform = (file, api) => { try { - const j = api.jscodeshift; + const j = file.path.includes('.ts') + ? api.jscodeshift.withParser('ts') + : api.jscodeshift; const root = j(file.source); const importStatement: ImportDeclaration = j.importDeclaration( From 6a5193583b57089a58bbb0e128268da0f4bc8e35 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Wed, 23 Oct 2024 11:49:09 +0530 Subject: [PATCH 57/71] feat: issues resolve --- .../src/util/config/expo-config-helper.ts | 30 +++++----------- .../gluestack-cli/src/util/config/index.ts | 28 +++++++++++---- .../src/util/config/next-config-helper.ts | 35 ++++++++----------- .../util/config/react-native-config-helper.ts | 32 +++++------------ packages/gluestack-cli/src/util/index.ts | 2 +- packages/gluestack-cli/src/util/init/index.ts | 4 +-- 6 files changed, 56 insertions(+), 75 deletions(-) diff --git a/packages/gluestack-cli/src/util/config/expo-config-helper.ts b/packages/gluestack-cli/src/util/config/expo-config-helper.ts index cb312b64..d955b2ba 100644 --- a/packages/gluestack-cli/src/util/config/expo-config-helper.ts +++ b/packages/gluestack-cli/src/util/config/expo-config-helper.ts @@ -2,7 +2,7 @@ import * as path from 'path'; import fg from 'fast-glob'; import * as fs from 'fs'; import { config } from '../../config'; -import { generateConfig, getFilePath } from '.'; +import { _currDir, generateConfig, getFilePath, pathResolver } from '.'; import { RawConfig, PROJECT_SHARED_IGNORE, @@ -14,8 +14,6 @@ import { log } from '@clack/prompts'; import { ensureFilesPromise } from '..'; import { commonInitialization } from '../init'; -const _currDir = process.cwd(); - // expo project type initialization async function getExpoProjectType(cwd: string): Promise { const files = await fg.glob('**/*', { @@ -68,28 +66,16 @@ async function isExpoSDK50(cwd: string): Promise { async function resolvedExpoPaths(resultConfig: ExpoResolvedConfig) { const resolvedExpoPaths = { tailwind: { - config: path - .resolve(_currDir, resultConfig.tailwind.config) - .replace(/\\/g, '/'), - css: path - .resolve(_currDir, resultConfig.tailwind.css) - .replace(/\\/g, '/'), + config: pathResolver(resultConfig.tailwind.config), + css: pathResolver(resultConfig.tailwind.css), }, config: { - babelConfig: path - .resolve(_currDir, resultConfig.config.babelConfig || '') - .replace(/\\/g, '/'), - metroConfig: path - .resolve(_currDir, resultConfig.config.metroConfig || '') - .replace(/\\/g, '/'), - tsConfig: path - .resolve(_currDir, resultConfig.config.tsConfig || '') - .replace(/\\/g, '/'), + babelConfig: pathResolver(resultConfig.config.babelConfig || ''), + metroConfig: pathResolver(resultConfig.config.metroConfig || ''), + tsConfig: pathResolver(resultConfig.config.tsConfig || ''), }, app: { - entry: path - .resolve(_currDir, resultConfig.app.entry || '') - .replace(/\\/g, '/'), + entry: pathResolver(resultConfig.app.entry || ''), type: resultConfig?.app?.type, sdk50: resultConfig?.app?.sdk50, }, @@ -195,7 +181,7 @@ async function generateConfigExpoApp(permission: boolean) { resolvedConfig.config.metroConfig, resolvedConfig.config.tsConfig, resolvedConfig.tailwind.css, - join(_currDir, 'nativewind-env.d.ts').replace(/\\/g, '/'), + pathResolver('nativewind-env.d.ts'), ]; const filesEnsured = await ensureFilesPromise(filesTobeEnsured); if (permission && filesEnsured) { diff --git a/packages/gluestack-cli/src/util/config/index.ts b/packages/gluestack-cli/src/util/config/index.ts index 0bfdc686..7a955527 100644 --- a/packages/gluestack-cli/src/util/config/index.ts +++ b/packages/gluestack-cli/src/util/config/index.ts @@ -9,6 +9,12 @@ const fileExtensions = ['.tsx', '.jsx', '.ts', '.js']; const possibleIndexFiles = ['_app', 'index', 'App']; const possibleDirectories = ['src', 'pages', 'app', 'components']; +const _currDir = process.cwd(); + +const pathResolver = (p: string) => { + return path.resolve(_currDir, p).replace(/\\/g, '/'); +}; + function findDirectory(rootDir: string, relativePaths: string[]) { for (const relPath of relativePaths) { const dirPath = path.join(rootDir, relPath); @@ -60,7 +66,9 @@ function getEntryPathAndComponentsPath(): { let FileExists: string[] = []; fileExtensions.forEach((ext) => { possibleIndexFiles.map((file) => { - if (fs.existsSync(path.join(projectRootPath, `${file}${ext}`))) { + if ( + fs.existsSync(path.join(projectRootPath, `${file}${ext}`).normalize()) + ) { FileExists.push(file); } }); @@ -68,19 +76,25 @@ function getEntryPathAndComponentsPath(): { // Check if any of the possible index files exist if (FileExists) { FileExists.forEach((file) => { - entryPath.push(`./${file}.{tsx,jsx,ts,js}`); + entryPath.push(path.join('.', `${file}.{tsx,jsx,ts,js}`)); }); } // Check if "src", "pages", "app" or "component" directories exist possibleDirectories.forEach((dir) => { - if (fs.existsSync(path.join(projectRootPath, dir))) { - entryPath.push(`./${dir}/**/*.{tsx,jsx,ts,js}`); + if (fs.existsSync(path.join(projectRootPath, dir).normalize())) { + entryPath.push(path.join('.', `${dir}/**/*.{tsx,jsx,ts,js}`)); } }); const resolvedPath = config.writableComponentsPath.split('/'); - if (!entryPath.includes(`./${resolvedPath[0]}/**/*.{tsx,jsx,ts,js}`)) { - componentsPath.push(`./${resolvedPath[0]}/**/*.{tsx,jsx,ts,js}`); + if ( + !entryPath.includes( + path.join('.', `${resolvedPath[0]}/**/*.{tsx,jsx,ts,js}`) + ) + ) { + componentsPath.push( + path.join('.', `${resolvedPath[0]}/**/*.{tsx,jsx,ts,js}`) + ); } entryPath = [...entryPath, ...componentsPath]; return { entryPath }; @@ -130,4 +144,6 @@ export { getComponentsPath, generateMonoRepoConfig, findDirectory, + pathResolver, + _currDir, }; diff --git a/packages/gluestack-cli/src/util/config/next-config-helper.ts b/packages/gluestack-cli/src/util/config/next-config-helper.ts index c69dc0c2..cb695d5d 100644 --- a/packages/gluestack-cli/src/util/config/next-config-helper.ts +++ b/packages/gluestack-cli/src/util/config/next-config-helper.ts @@ -2,7 +2,13 @@ import * as path from 'path'; import fg from 'fast-glob'; import { pathExists, readFile, writeFile } from 'fs-extra'; import { config } from '../../config'; -import { findDirectory, generateConfig, getFilePath } from '.'; +import { + findDirectory, + generateConfig, + getFilePath, + pathResolver, + _currDir, +} from '.'; import { RawConfig, NextResolvedConfig, @@ -14,7 +20,6 @@ import { log } from '@clack/prompts'; import { ensureFilesPromise } from '..'; import { commonInitialization } from '../init'; -const _currDir = process.cwd(); //next project type initialization async function getNextProjectType(cwd: string): Promise { const files = await fg.glob('**/*', { @@ -43,28 +48,16 @@ async function getNextProjectType(cwd: string): Promise { async function resolvedNextJsPaths(resultConfig: NextResolvedConfig) { const resolvedNextJsPaths = { tailwind: { - config: path - .resolve(_currDir, resultConfig.tailwind.config) - .replace(/\\/g, '/'), - css: path - .resolve(_currDir, resultConfig.tailwind.css) - .replace(/\\/g, '/'), + config: pathResolver(resultConfig.tailwind.config), + css: pathResolver(resultConfig.tailwind.css), }, config: { - postCssConfig: path - .resolve(_currDir, resultConfig.config.postCssConfig || '') - .replace(/\\/g, '/'), - nextConfig: path - .resolve(_currDir, resultConfig.config.nextConfig || '') - .replace(/\\/g, '/'), - tsConfig: path - .resolve(_currDir, resultConfig.config.tsConfig || '') - .replace(/\\/g, '/'), + postCssConfig: pathResolver(resultConfig.config.postCssConfig || ''), + nextConfig: pathResolver(resultConfig.config.nextConfig || ''), + tsConfig: pathResolver(resultConfig.config.tsConfig || ''), }, app: { - entry: path - .resolve(_currDir, resultConfig.app.entry || '') - .replace(/\\/g, '/'), + entry: pathResolver(resultConfig.app.entry || ''), type: resultConfig?.app?.type, registry: resultConfig?.app?.registry ? resultConfig.app.registry.replace(/\\/g, '/') @@ -197,7 +190,7 @@ async function generateConfigNextApp(permission: boolean) { resolvedConfig.config.tsConfig, resolvedConfig.tailwind.css, resolvedConfig.config.postCssConfig, - path.resolve(_currDir, 'nativewind-env.d.ts').replace(/\\/g, '/'), + pathResolver('nativewind-env.d.ts'), ]; const filesEnsured = await ensureFilesPromise(filesTobeEnsured); if (permission && filesEnsured) { diff --git a/packages/gluestack-cli/src/util/config/react-native-config-helper.ts b/packages/gluestack-cli/src/util/config/react-native-config-helper.ts index a7cb0b77..d9c52739 100644 --- a/packages/gluestack-cli/src/util/config/react-native-config-helper.ts +++ b/packages/gluestack-cli/src/util/config/react-native-config-helper.ts @@ -1,5 +1,5 @@ import * as path from 'path'; -import { generateConfig, getFilePath } from '.'; +import { generateConfig, getFilePath, pathResolver } from '.'; import { RawConfig, ReactNativeResolvedConfig } from './config-types'; import { ensureFilesPromise, getRelativePath } from '..'; import { config } from '../../config'; @@ -8,36 +8,22 @@ import { execSync } from 'child_process'; import { log } from '@clack/prompts'; import { commonInitialization } from '../init'; -const _currDir = process.cwd(); - //react-native project type initialization async function resolvedReactNativePaths( resultConfig: ReactNativeResolvedConfig ) { const resolvedReactNativePaths = { tailwind: { - config: path - .resolve(_currDir, resultConfig.tailwind.config) - .replace(/\\/g, '/'), - css: path - .resolve(_currDir, resultConfig.tailwind.css) - .replace(/\\/g, '/'), + config: pathResolver(resultConfig.tailwind.config), + css: pathResolver(resultConfig.tailwind.css), }, config: { - babelConfig: path - .resolve(_currDir, resultConfig.config.babelConfig || '') - .replace(/\\/g, '/'), - metroConfig: path - .resolve(_currDir, resultConfig.config.metroConfig || '') - .replace(/\\/g, '/'), - tsConfig: path - .resolve(_currDir, resultConfig.config.tsConfig || '') - .replace(/\\/g, '/'), + babelConfig: pathResolver(resultConfig.config.babelConfig || ''), + metroConfig: pathResolver(resultConfig.config.metroConfig || ''), + tsConfig: pathResolver(resultConfig.config.tsConfig || ''), }, app: { - entry: path - .resolve(_currDir, resultConfig.app.entry || '') - .replace(/\\/g, '/'), + entry: pathResolver(resultConfig.app.entry || ''), }, }; return resolvedReactNativePaths; @@ -128,7 +114,7 @@ async function generateConfigRNApp(permission: boolean) { tsConfig: tsConfigPath.length ? tsConfigPath : 'tsconfig.json', }, app: { - entry: path.resolve(_currDir, entryPath).replace(/\\/g, '/'), + entry: pathResolver(entryPath), }, }; @@ -141,7 +127,7 @@ async function generateConfigRNApp(permission: boolean) { resolvedConfig.config.metroConfig, resolvedConfig.config.tsConfig, resolvedConfig.tailwind.css, - join(_currDir, 'nativewind-env.d.ts'), + pathResolver('nativewind-env.d.ts'), ]; const filesEnsured = await ensureFilesPromise(filesTobeEnsured); if (permission && filesEnsured) { diff --git a/packages/gluestack-cli/src/util/index.ts b/packages/gluestack-cli/src/util/index.ts index 56124e3e..2d5dad32 100644 --- a/packages/gluestack-cli/src/util/index.ts +++ b/packages/gluestack-cli/src/util/index.ts @@ -234,12 +234,12 @@ const installDependencies = async ( additionalDependencies?: ComponentConfig | undefined ): Promise => { try { - await ensureLegacyPeerDeps(); let versionManager = config.packageManager || findLockFileType() || (await promptVersionManager()); config.packageManager = versionManager; + await ensureLegacyPeerDeps(); const dependenciesToInstall: { dependencies: Dependency; diff --git a/packages/gluestack-cli/src/util/init/index.ts b/packages/gluestack-cli/src/util/init/index.ts index 1fea5dc7..d1307460 100644 --- a/packages/gluestack-cli/src/util/init/index.ts +++ b/packages/gluestack-cli/src/util/init/index.ts @@ -308,7 +308,7 @@ const filesToOverride = (projectType: string) => { case config.nextJsProject: return [ 'next.config.*', - 'tailwind.config.js', + 'tailwind.config.*', 'global.css', 'tsconfig.json', ]; @@ -316,7 +316,7 @@ const filesToOverride = (projectType: string) => { return [ 'babel.config.js', 'metro.config.js', - 'tailwind.config.js', + 'tailwind.config.*', 'global.css', 'tsconfig.json', ]; From d9df9860932f7bb6dc10457f617259c8e3b20c1b Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Wed, 23 Oct 2024 11:56:41 +0530 Subject: [PATCH 58/71] v0.7.12 --- packages/gluestack-cli/package.json | 2 +- packages/gluestack-cli/src/dependencies.ts | 2 +- packages/gluestack-cli/src/util/index.ts | 8 ++++++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/gluestack-cli/package.json b/packages/gluestack-cli/package.json index 18f23177..5bc48fe8 100644 --- a/packages/gluestack-cli/package.json +++ b/packages/gluestack-cli/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for easily adding components from gluestack to your projects.", - "version": "0.7.10", + "version": "0.7.12", "license": "MIT", "main": "dist/index.js", "files": [ diff --git a/packages/gluestack-cli/src/dependencies.ts b/packages/gluestack-cli/src/dependencies.ts index bbaddeed..f2020fef 100644 --- a/packages/gluestack-cli/src/dependencies.ts +++ b/packages/gluestack-cli/src/dependencies.ts @@ -44,7 +44,7 @@ const dependenciesConfig: Dependencies = { tailwindcss: '', '@gluestack-ui/overlay': 'latest', '@gluestack-ui/toast': 'latest', - '@gluestack-ui/nativewind-utils': 'latest', + '@gluestack-ui/nativewind-utils': '1.0.23', 'react-native-svg': '13.4.0', nativewind: '4.1.10', }, diff --git a/packages/gluestack-cli/src/util/index.ts b/packages/gluestack-cli/src/util/index.ts index 8d9c5555..7632a9a1 100644 --- a/packages/gluestack-cli/src/util/index.ts +++ b/packages/gluestack-cli/src/util/index.ts @@ -489,10 +489,14 @@ async function getAdditionalDependencies( style: string ) { try { - let additionalDependencies = { + let additionalDependencies: { + dependencies: {}; + devDependencies?: {}; + } = { dependencies: {}, - devDependencies: {} || undefined, + devDependencies: {}, }; + if (style === config.nativeWindRootPath) { if (projectType && projectType !== 'library') { additionalDependencies.dependencies = From 36d2d9288f3b4c77db950e86d4dae78d570fa4f7 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Wed, 23 Oct 2024 12:06:14 +0530 Subject: [PATCH 59/71] v0.7.13 --- packages/gluestack-cli/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gluestack-cli/package.json b/packages/gluestack-cli/package.json index 5bc48fe8..a915e7af 100644 --- a/packages/gluestack-cli/package.json +++ b/packages/gluestack-cli/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for easily adding components from gluestack to your projects.", - "version": "0.7.12", + "version": "0.7.13", "license": "MIT", "main": "dist/index.js", "files": [ From 508db00007a7e73e4966db92d396973de88c2428 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Wed, 23 Oct 2024 12:46:00 +0530 Subject: [PATCH 60/71] fix: quick fixes --- packages/gluestack-cli/src/commands/add.ts | 12 +++++++++++- packages/gluestack-cli/src/dependencies.ts | 2 +- packages/gluestack-cli/src/util/add/index.ts | 4 ++-- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/packages/gluestack-cli/src/commands/add.ts b/packages/gluestack-cli/src/commands/add.ts index 0fffe9a2..9843b443 100644 --- a/packages/gluestack-cli/src/commands/add.ts +++ b/packages/gluestack-cli/src/commands/add.ts @@ -4,8 +4,17 @@ import { handleError } from '../util/handle-error'; import { log } from '@clack/prompts'; import { componentAdder, hookAdder, isHookFromConfig } from '../util/add'; import { config } from '../config'; -import { checkWritablePath, isValidPath, projectRootPath } from '../util'; +import { + checkWritablePath, + isValidPath, + projectRootPath, + cloneRepositoryAtRoot, +} from '../util'; import { checkIfInitialized, getComponentsPath } from '../util/config'; +import { join } from 'path'; +import os from 'os'; + +const _homeDir = os.homedir(); const addOptionsSchema = z.object({ components: z.string().optional(), @@ -53,6 +62,7 @@ export const add = new Command() ); process.exit(1); } + await cloneRepositoryAtRoot(join(_homeDir, config.gluestackDir)); //function to get current path where GUIProvider is located const currWritablePath = await getComponentsPath(projectRootPath); if (currWritablePath) { diff --git a/packages/gluestack-cli/src/dependencies.ts b/packages/gluestack-cli/src/dependencies.ts index f2020fef..4fa0ee17 100644 --- a/packages/gluestack-cli/src/dependencies.ts +++ b/packages/gluestack-cli/src/dependencies.ts @@ -46,7 +46,7 @@ const dependenciesConfig: Dependencies = { '@gluestack-ui/toast': 'latest', '@gluestack-ui/nativewind-utils': '1.0.23', 'react-native-svg': '13.4.0', - nativewind: '4.1.10', + nativewind: '4.0.36', }, devDependencies: { jscodeshift: '0.15.2', diff --git a/packages/gluestack-cli/src/util/add/index.ts b/packages/gluestack-cli/src/util/add/index.ts index cda15041..b6b0774d 100644 --- a/packages/gluestack-cli/src/util/add/index.ts +++ b/packages/gluestack-cli/src/util/add/index.ts @@ -21,7 +21,6 @@ const componentAdder = async ({ }) => { try { console.log(`\n\x1b[1mAdding new component...\x1b[0m\n`); - await cloneRepositoryAtRoot(join(_homeDir, config.gluestackDir)); let hooksToAdd: string[] = []; if ( requestedComponent && @@ -54,7 +53,8 @@ const componentAdder = async ({ ); await writeComponent(component, targetPath); - await hookAdder({ requestedHook: hooksToAdd }); + if (hooksToAdd.length > 0) + await hookAdder({ requestedHook: hooksToAdd }); }) ) .then(async () => { From 5af72d444b32d55632d3c42947090ad5e02119d0 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Wed, 23 Oct 2024 13:18:43 +0530 Subject: [PATCH 61/71] fix: jsxImportSorce fix in next --- packages/gluestack-cli/src/util/index.ts | 2 +- packages/gluestack-cli/src/util/init/index.ts | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/gluestack-cli/src/util/index.ts b/packages/gluestack-cli/src/util/index.ts index 3c73293c..f9e381f1 100644 --- a/packages/gluestack-cli/src/util/index.ts +++ b/packages/gluestack-cli/src/util/index.ts @@ -237,12 +237,12 @@ const installDependencies = async ( additionalDependencies?: ComponentConfig | undefined ): Promise => { try { - await ensureLegacyPeerDeps(); let versionManager = config.packageManager || findLockFileType() || (await promptVersionManager()); config.packageManager = versionManager; + await ensureLegacyPeerDeps(); const dependenciesToInstall: { dependencies: Dependency; diff --git a/packages/gluestack-cli/src/util/init/index.ts b/packages/gluestack-cli/src/util/init/index.ts index dda2ed23..e64b4791 100644 --- a/packages/gluestack-cli/src/util/init/index.ts +++ b/packages/gluestack-cli/src/util/init/index.ts @@ -155,11 +155,14 @@ function updatePaths( paths[key] = Array.from(new Set([...(paths[key] || []), ...newValues])); } //update tsconfig.json -async function updateTSConfig(projectType: string, config: any): Promise { +async function updateTSConfig( + projectType: string, + resolvedConfig: any +): Promise { try { - const configPath = config.config.tsConfig; + const configPath = resolvedConfig.config.tsConfig; let tsConfig: TSConfig = await readTSConfig(configPath); - let tailwindConfig = config.tailwind.config; + let tailwindConfig = resolvedConfig.tailwind.config; const tailwindConfigFileName = path.basename(tailwindConfig); tsConfig.compilerOptions = tsConfig.compilerOptions || {}; From eaa7ad674f952f57acb38577cd5961cca8682cd2 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Wed, 23 Oct 2024 13:22:08 +0530 Subject: [PATCH 62/71] v0.7.14 --- packages/gluestack-cli/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gluestack-cli/package.json b/packages/gluestack-cli/package.json index 862856d7..cbbf6161 100644 --- a/packages/gluestack-cli/package.json +++ b/packages/gluestack-cli/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for easily adding components from gluestack to your projects.", - "version": "0.7.10-alpha.1.0", + "version": "0.7.14", "license": "MIT", "main": "dist/index.js", "files": [ From 1ed0b3da6ad670e9fd2edbbd2ef4fde637630486 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Wed, 23 Oct 2024 14:02:42 +0530 Subject: [PATCH 63/71] v0.7.15-alpha.0 --- packages/gluestack-cli/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gluestack-cli/package.json b/packages/gluestack-cli/package.json index cbbf6161..ce37515b 100644 --- a/packages/gluestack-cli/package.json +++ b/packages/gluestack-cli/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for easily adding components from gluestack to your projects.", - "version": "0.7.14", + "version": "0.7.15-alpha.0", "license": "MIT", "main": "dist/index.js", "files": [ From 698ef7d15abfffff5564e6ea54f0869a32acc282 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Wed, 23 Oct 2024 14:07:44 +0530 Subject: [PATCH 64/71] feat: add use-client transformer --- .../src/util/config/config-types.ts | 1 + .../src/util/config/next-config-helper.ts | 14 +++++++++ .../nextjs/next-add-page-type-transform.ts | 30 +++++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 packages/gluestack-cli/template/codemods/nextjs/next-add-page-type-transform.ts diff --git a/packages/gluestack-cli/src/util/config/config-types.ts b/packages/gluestack-cli/src/util/config/config-types.ts index 96d92496..147a0b0d 100644 --- a/packages/gluestack-cli/src/util/config/config-types.ts +++ b/packages/gluestack-cli/src/util/config/config-types.ts @@ -35,6 +35,7 @@ export const NextResolvedConfigSchema = z.object({ type: z.string().optional(), entry: z.string(), registry: z.string().optional(), + page: z.string().optional(), }), }); diff --git a/packages/gluestack-cli/src/util/config/next-config-helper.ts b/packages/gluestack-cli/src/util/config/next-config-helper.ts index feef2ef1..4727e154 100644 --- a/packages/gluestack-cli/src/util/config/next-config-helper.ts +++ b/packages/gluestack-cli/src/util/config/next-config-helper.ts @@ -58,6 +58,9 @@ async function resolvedNextJsPaths(resultConfig: NextResolvedConfig) { entry: path.resolve(_currDir, resultConfig.app.entry || ''), type: resultConfig?.app?.type, registry: resultConfig?.app?.registry, + page: resultConfig?.app?.page + ? path.resolve(_currDir, resultConfig.app.page) + : '', }, }; return resolvedNextJsPaths; @@ -100,6 +103,13 @@ async function initNatiwindNextApp( 'utf8' ); await writeFile(resolvedConfig.app.registry, registryContent, 'utf8'); + const pageTransformerPath = join( + `${NextTransformer}/next-add-page-type-transform.ts` + ); + resolvedConfig.app.page?.length && + execSync( + `npx jscodeshift -t ${pageTransformerPath} ${resolvedConfig.app.page}` + ); } if (resolvedConfig.app?.entry?.includes('_app')) { const pageDirPath = path.dirname(resolvedConfig.app.entry); @@ -145,6 +155,9 @@ async function generateConfigNextApp(permission: boolean) { const appDirectory = findDirectory(_currDir, ['src/app', 'app']); registryPath = path.join(_currDir, appDirectory, 'registry.tsx'); } + const pagePath = entryPath.includes('layout.') + ? await getFilePath(['**/*page.*']) + : undefined; const gluestackConfig: RawConfig = { tailwind: { @@ -177,6 +190,7 @@ async function generateConfigNextApp(permission: boolean) { type: projectType, entry: entryPath, registry: registryPath, + page: pagePath, }, }; diff --git a/packages/gluestack-cli/template/codemods/nextjs/next-add-page-type-transform.ts b/packages/gluestack-cli/template/codemods/nextjs/next-add-page-type-transform.ts new file mode 100644 index 00000000..982327bf --- /dev/null +++ b/packages/gluestack-cli/template/codemods/nextjs/next-add-page-type-transform.ts @@ -0,0 +1,30 @@ +import { Transform } from 'jscodeshift'; + +const transform: Transform = (file, api) => { + try { + const j = api.jscodeshift.withParser('tsx'); + const root = j(file.source); + + // Check if 'use client' already exists + const hasUseClient = + root + .find(j.ExpressionStatement, { + expression: { value: 'use client' }, + }) + .size() > 0; + + // If 'use client' is not present, append it at the top + if (!hasUseClient) { + const useClientDirective = j.expressionStatement(j.literal('use client')); + + // Insert 'use client' at the top of the file + root.get().node.program.body.unshift(useClientDirective); + } + + return root.toSource(); + } catch (err) { + console.log(`\x1b[31mError: ${err as Error}\x1b[0m`); + } +}; + +export default transform; From 2f098fd59bfcea5e840118e511fa8a7b71eac893 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Wed, 23 Oct 2024 14:08:22 +0530 Subject: [PATCH 65/71] v0.7.16 --- packages/gluestack-cli/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gluestack-cli/package.json b/packages/gluestack-cli/package.json index ce37515b..fd2681c2 100644 --- a/packages/gluestack-cli/package.json +++ b/packages/gluestack-cli/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for easily adding components from gluestack to your projects.", - "version": "0.7.15-alpha.0", + "version": "0.7.16", "license": "MIT", "main": "dist/index.js", "files": [ From 1380a23926be6d9f96bf94a7c889803879a425d3 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Mon, 28 Oct 2024 15:30:13 +0530 Subject: [PATCH 66/71] fix: error handling --- packages/gluestack-cli/src/dependencies.ts | 2 +- packages/gluestack-cli/src/util/add/index.ts | 2 +- .../src/util/config/expo-config-helper.ts | 2 +- .../src/util/config/next-config-helper.ts | 117 +++++++++--------- .../util/config/react-native-config-helper.ts | 2 +- packages/gluestack-cli/src/util/index.ts | 20 +-- packages/gluestack-cli/src/util/init/index.ts | 8 +- 7 files changed, 77 insertions(+), 76 deletions(-) diff --git a/packages/gluestack-cli/src/dependencies.ts b/packages/gluestack-cli/src/dependencies.ts index 7aab3499..4ba3d27a 100644 --- a/packages/gluestack-cli/src/dependencies.ts +++ b/packages/gluestack-cli/src/dependencies.ts @@ -88,7 +88,7 @@ async function getProjectBasedDependencies( } return { dependencies: {}, devDependencies: {} }; } catch (error) { - log.error(`\x1b[31mError: ${(error as Error).message}\x1b[0m`); + throw new Error((error as Error).message); } } diff --git a/packages/gluestack-cli/src/util/add/index.ts b/packages/gluestack-cli/src/util/add/index.ts index c089cf96..5bd7cad4 100644 --- a/packages/gluestack-cli/src/util/add/index.ts +++ b/packages/gluestack-cli/src/util/add/index.ts @@ -74,7 +74,7 @@ const componentAdder = async ({ } if (hooksToAdd.length > 0) await hookAdder(hooksToAdd); } catch (err) { - log.error(`\x1b[31mError: ${(err as Error).message}\x1b[0m`); + throw new Error((err as Error).message); } }; diff --git a/packages/gluestack-cli/src/util/config/expo-config-helper.ts b/packages/gluestack-cli/src/util/config/expo-config-helper.ts index d955b2ba..3f3a9e9e 100644 --- a/packages/gluestack-cli/src/util/config/expo-config-helper.ts +++ b/packages/gluestack-cli/src/util/config/expo-config-helper.ts @@ -127,7 +127,7 @@ async function initNatiwindExpoApp( }); await commonInitialization(config.expoProject, resolvedConfig, permission); } catch (err) { - log.error(`\x1b[31mError: ${err as Error}\x1b[0m`); + throw new Error((err as Error).message); } } diff --git a/packages/gluestack-cli/src/util/config/next-config-helper.ts b/packages/gluestack-cli/src/util/config/next-config-helper.ts index db786abe..1d21c124 100644 --- a/packages/gluestack-cli/src/util/config/next-config-helper.ts +++ b/packages/gluestack-cli/src/util/config/next-config-helper.ts @@ -1,48 +1,47 @@ -import * as path from "path"; -import fg from "fast-glob"; -import { pathExists, readFile, writeFile } from "fs-extra"; -import { config } from "../../config"; +import * as path from 'path'; +import fg from 'fast-glob'; +import { pathExists, readFile, writeFile } from 'fs-extra'; +import { config } from '../../config'; import { findDirectory, generateConfig, getFilePath, pathResolver, _currDir, -} from "."; +} from '.'; import { RawConfig, NextResolvedConfig, PROJECT_SHARED_IGNORE, -} from "./config-types"; -import { join, relative } from "path"; -import { execSync } from "child_process"; -import { log } from "@clack/prompts"; -import { ensureFilesPromise } from ".."; -import { commonInitialization } from "../init"; +} from './config-types'; +import { join, relative } from 'path'; +import { execSync } from 'child_process'; +import { ensureFilesPromise } from '..'; +import { commonInitialization } from '../init'; //next project type initialization async function getNextProjectType(cwd: string): Promise { - const files = await fg.glob("**/*", { + const files = await fg.glob('**/*', { cwd, deep: 3, ignore: PROJECT_SHARED_IGNORE, }); - const isNextProject = files.find((file) => file.startsWith("next.config.")); + const isNextProject = files.find((file) => file.startsWith('next.config.')); if (!isNextProject) { return undefined; } - const isUsingSrcDir = await pathExists(path.resolve(cwd, "src")); + const isUsingSrcDir = await pathExists(path.resolve(cwd, 'src')); const isUsingAppDir = await pathExists( - path.resolve(cwd, `${isUsingSrcDir ? "src/" : ""}app`) + path.resolve(cwd, `${isUsingSrcDir ? 'src/' : ''}app`) ); if (isUsingAppDir) { - return isUsingSrcDir ? "next-app-src" : "next-app"; + return isUsingSrcDir ? 'next-app-src' : 'next-app'; } - return isUsingSrcDir ? "next-pages-src" : "next-pages"; + return isUsingSrcDir ? 'next-pages-src' : 'next-pages'; } async function resolvedNextJsPaths(resultConfig: NextResolvedConfig) { @@ -52,19 +51,19 @@ async function resolvedNextJsPaths(resultConfig: NextResolvedConfig) { css: pathResolver(resultConfig.tailwind.css), }, config: { - postCssConfig: pathResolver(resultConfig.config.postCssConfig || ""), - nextConfig: pathResolver(resultConfig.config.nextConfig || ""), - tsConfig: pathResolver(resultConfig.config.tsConfig || ""), + postCssConfig: pathResolver(resultConfig.config.postCssConfig || ''), + nextConfig: pathResolver(resultConfig.config.nextConfig || ''), + tsConfig: pathResolver(resultConfig.config.tsConfig || ''), }, app: { - entry: pathResolver(resultConfig.app.entry || ""), + entry: pathResolver(resultConfig.app.entry || ''), type: resultConfig?.app?.type, registry: resultConfig?.app?.registry - ? resultConfig.app.registry.replace(/\\/g, "/") + ? resultConfig.app.registry.replace(/\\/g, '/') : undefined, page: resultConfig?.app?.page ? path.resolve(_currDir, resultConfig.app.page) - : "", + : '', }, }; return resolvedNextJsPaths; @@ -82,13 +81,13 @@ async function initNatiwindNextApp( ); const nextConfigPath = resolvedConfig.config.nextConfig; - let nextTransformerPath = ""; - let fileType = ""; + let nextTransformerPath = ''; + let fileType = ''; - if (nextConfigPath?.endsWith(".mjs") || nextConfigPath?.endsWith(".ts")) { - fileType = "mjs"; - } else if (nextConfigPath?.endsWith(".js")) { - fileType = "js"; + if (nextConfigPath?.endsWith('.mjs') || nextConfigPath?.endsWith('.ts')) { + fileType = 'mjs'; + } else if (nextConfigPath?.endsWith('.js')) { + fileType = 'js'; } nextTransformerPath = join( `${NextTransformer}/next-config-${fileType}-transform.ts` @@ -98,15 +97,15 @@ async function initNatiwindNextApp( execSync(`npx jscodeshift -t ${nextTransformerPath} ${nextConfigPath}`); } if ( - resolvedConfig.app?.entry?.includes("layout") && + resolvedConfig.app?.entry?.includes('layout') && resolvedConfig.app.registry ) { // if app router add registry file to root const registryContent = await readFile( - join(__dirname, config.templatesDir, "common", "registry.tsx"), - "utf8" + join(__dirname, config.templatesDir, 'common', 'registry.tsx'), + 'utf8' ); - await writeFile(resolvedConfig.app.registry, registryContent, "utf8"); + await writeFile(resolvedConfig.app.registry, registryContent, 'utf8'); const pageTransformerPath = join( `${NextTransformer}/next-add-page-type-transform.ts` ); @@ -115,9 +114,9 @@ async function initNatiwindNextApp( `npx jscodeshift -t ${pageTransformerPath} ${resolvedConfig.app.page}` ); } - if (resolvedConfig.app?.entry?.includes("_app")) { + if (resolvedConfig.app?.entry?.includes('_app')) { const pageDirPath = path.dirname(resolvedConfig.app.entry); - const docsPagePath = join(pageDirPath, "_document.tsx"); + const docsPagePath = join(pageDirPath, '_document.tsx'); const transformerPath = join( `${NextTransformer}/next-document-update-transform.ts` ); @@ -128,7 +127,7 @@ async function initNatiwindNextApp( `${NextTransformer}/next-add-provider-transform.ts` ); const rawCssPath = relative(_currDir, resolvedConfig.tailwind.css); - const cssImportPath = "@/".concat(rawCssPath); + const cssImportPath = '@/'.concat(rawCssPath); execSync( `npx jscodeshift -t ${transformerPath} ${resolvedConfig.app.entry} --componentsPath=${config.writableComponentsPath} --cssImportPath=${cssImportPath} ` ); @@ -138,36 +137,36 @@ async function initNatiwindNextApp( permission ); } catch (err) { - log.error(`\x1b[31mError: ${err as Error}\x1b[0m`); + throw new Error((err as Error).message); } } async function generateConfigNextApp(permission: boolean) { const projectType = await getNextProjectType(_currDir); - const entryPath = await getFilePath(["**/*layout.*", "**/*_app.*"]); + const entryPath = await getFilePath(['**/*layout.*', '**/*_app.*']); const globalCssPath = await getFilePath([ - "**/*globals.css", - "**/*global.css", + '**/*globals.css', + '**/*global.css', ]); - const tailwindConfigPath = await getFilePath(["tailwind.config.*"]); - const postCssConfigPath = await getFilePath(["postcss.config.*"]); - const nextConfigPath = await getFilePath(["next.config.*"]); - const tsConfigPath = await getFilePath(["tsconfig.*"]); - let registryPath = ""; - if (projectType?.includes("app")) { - const appDirectory = findDirectory(_currDir, ["src/app", "app"]); - registryPath = path.resolve(_currDir, appDirectory, "registry.tsx"); + const tailwindConfigPath = await getFilePath(['tailwind.config.*']); + const postCssConfigPath = await getFilePath(['postcss.config.*']); + const nextConfigPath = await getFilePath(['next.config.*']); + const tsConfigPath = await getFilePath(['tsconfig.*']); + let registryPath = ''; + if (projectType?.includes('app')) { + const appDirectory = findDirectory(_currDir, ['src/app', 'app']); + registryPath = path.resolve(_currDir, appDirectory, 'registry.tsx'); } - const pagePath = entryPath.includes("layout.") - ? await getFilePath(["**/*page.*"]) + const pagePath = entryPath.includes('layout.') + ? await getFilePath(['**/*page.*']) : undefined; const gluestackConfig: RawConfig = { tailwind: { config: tailwindConfigPath.length ? tailwindConfigPath - : "tailwind.config.js", - css: globalCssPath.length ? globalCssPath : "global.css", + : 'tailwind.config.js', + css: globalCssPath.length ? globalCssPath : 'global.css', }, app: { entry: entryPath, @@ -179,15 +178,15 @@ async function generateConfigNextApp(permission: boolean) { tailwind: { config: tailwindConfigPath.length ? tailwindConfigPath - : "tailwind.config.js", - css: globalCssPath.length ? globalCssPath : "global.css", + : 'tailwind.config.js', + css: globalCssPath.length ? globalCssPath : 'global.css', }, config: { postCssConfig: postCssConfigPath.length ? postCssConfigPath - : "postcss.config.js", - nextConfig: nextConfigPath.length ? nextConfigPath : "next.config.js", - tsConfig: tsConfigPath.length ? tsConfigPath : "tsconfig.json", + : 'postcss.config.js', + nextConfig: nextConfigPath.length ? nextConfigPath : 'next.config.js', + tsConfig: tsConfigPath.length ? tsConfigPath : 'tsconfig.json', }, app: { type: projectType, @@ -200,11 +199,11 @@ async function generateConfigNextApp(permission: boolean) { generateConfig(gluestackConfig); const resolvedConfig = await resolvedNextJsPaths(resolvedGluestackConfig); const filesTobeEnsured = [ - resolvedConfig.app.registry ?? "", + resolvedConfig.app.registry ?? '', resolvedConfig.config.tsConfig, resolvedConfig.tailwind.css, resolvedConfig.config.postCssConfig, - pathResolver("nativewind-env.d.ts"), + pathResolver('nativewind-env.d.ts'), ]; const filesEnsured = await ensureFilesPromise(filesTobeEnsured); if (permission && filesEnsured) { diff --git a/packages/gluestack-cli/src/util/config/react-native-config-helper.ts b/packages/gluestack-cli/src/util/config/react-native-config-helper.ts index d9c52739..d16e511e 100644 --- a/packages/gluestack-cli/src/util/config/react-native-config-helper.ts +++ b/packages/gluestack-cli/src/util/config/react-native-config-helper.ts @@ -74,7 +74,7 @@ async function initNatiwindRNApp( execSync('npx pod-install', { stdio: 'inherit' }); } catch (err) { - log.error(`\x1b[31mError: ${err as Error}\x1b[0m`); + throw new Error((err as Error).message); } } diff --git a/packages/gluestack-cli/src/util/index.ts b/packages/gluestack-cli/src/util/index.ts index 2d5dad32..8deb5277 100644 --- a/packages/gluestack-cli/src/util/index.ts +++ b/packages/gluestack-cli/src/util/index.ts @@ -103,8 +103,8 @@ const cloneRepositoryAtRoot = async (rootPath: string) => { await cloneComponentRepo(rootPath, config.repoUrl); } } catch (err) { - log.error(`\x1b[31m Cloning failed, ${(err as Error).message}\x1b[0m`); - process.exit(1); + log.error(`\x1b[31m Cloning failed.\x1b[0m`); + throw new Error((err as Error).message); } }; @@ -124,8 +124,7 @@ const cloneComponentRepo = async ( s.stop('\x1b[32m' + 'Cloning successful.' + '\x1b[0m'); } catch (err) { s.stop('\x1b[31m' + 'Cloning failed' + '\x1b[0m'); - log.error(`\x1b[31mError: ${(err as Error).message}\x1b[0m`); - process.exit(1); + throw new Error((err as Error).message); } }; @@ -147,8 +146,10 @@ const pullComponentRepo = async (targetpath: string): Promise => { retry++; } } - if (!success) s.stop('\x1b[31m' + 'Pulling failed!' + '\x1b[0m'); - else s.stop('Git pull successful.'); + if (!success) { + s.stop('\x1b[31m' + 'Pulling failed!' + '\x1b[0m'); + throw new Error('Error pulling remote branch!') + } else s.stop('Git pull successful.'); }; const tryGitPull = async (targetPath: string): Promise => { @@ -325,11 +326,12 @@ const installDependencies = async ( s.stop(`Dependencies have been installed successfully.`); } catch (err) { - throw new Error('Error installing dependencies.'); + throw new Error( + `Error installing dependencies: ${(err as Error).message}` + ); } } catch (err) { - log.error(`\x1b[31mError: ${(err as Error).message}\x1b[0m`); - process.exit(1); + throw new Error((err as Error).message); } }; diff --git a/packages/gluestack-cli/src/util/init/index.ts b/packages/gluestack-cli/src/util/init/index.ts index ef18c002..3e6e735e 100644 --- a/packages/gluestack-cli/src/util/init/index.ts +++ b/packages/gluestack-cli/src/util/init/index.ts @@ -72,6 +72,7 @@ const InitializeGlueStack = async ({ ); } catch (err) { log.error(`\x1b[31mError occured in init. (${err as Error})\x1b[0m`); + process.exit(1); } }; @@ -93,9 +94,8 @@ async function addProvider() { await fs.ensureDir(targetPath); await fs.copy(sourcePath, targetPath); } catch (err) { - log.error( - `\x1b[31mError occured while adding the provider. (${err as Error})\x1b[0m` - ); + log.error(`\x1b[31mError occured while adding the provider.\x1b[0m`); + throw new Error((err as Error).message); } } @@ -270,7 +270,7 @@ async function commonInitialization( ); } } catch (err) { - log.error(`\x1b[31mError: ${err as Error}\x1b[0m`); + throw new Error((err as Error).message); } } From 518ae56d5daffde52d254df24c04ed99bc71dac9 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Tue, 5 Nov 2024 15:54:25 +0530 Subject: [PATCH 67/71] fix: tailwindConfig path contents --- packages/gluestack-cli/src/util/init/index.ts | 25 ++++++++-- .../codemods/tailwind-config-transform.ts | 49 ++++++++++++++++--- 2 files changed, 62 insertions(+), 12 deletions(-) diff --git a/packages/gluestack-cli/src/util/init/index.ts b/packages/gluestack-cli/src/util/init/index.ts index 3e6e735e..e34c51e3 100644 --- a/packages/gluestack-cli/src/util/init/index.ts +++ b/packages/gluestack-cli/src/util/init/index.ts @@ -104,6 +104,8 @@ async function updateTailwindConfig( resolvedConfig: RawConfig, projectType: string ) { + // Create a temporary file to store options + const tempFilePath = join(os.tmpdir(), 'jscodeshift-options.json'); try { const tailwindConfigRootPath = join( _homeDir, @@ -113,17 +115,30 @@ async function updateTailwindConfig( const tailwindConfigPath = resolvedConfig.tailwind.config; await fs.copy(tailwindConfigRootPath, tailwindConfigPath); // Codemod to update tailwind.config.js usage - const { entryPath } = getEntryPathAndComponentsPath(); - const allNewPaths = JSON.stringify(entryPath); + const { entryPath } = getEntryPathAndComponentsPath(); // entryPaths is an array of strings + + fs.writeFileSync( + tempFilePath, + JSON.stringify({ paths: entryPath }) // Write paths and projectType to the file + ); const transformerPath = join( __dirname, `${config.codeModesDir}/tailwind-config-transform.ts` ); - execSync( - `npx jscodeshift -t ${transformerPath} ${tailwindConfigPath} --paths='${allNewPaths}' --projectType='${projectType}' ` - ); + + // Build the jscodeshift command + const command = `npx jscodeshift -t ${transformerPath} ${tailwindConfigPath} --optionsFile=${tempFilePath} --projectType=${projectType}`; + + // Execute the command + execSync(command); + // Delete the temporary file after usage + fs.unlinkSync(tempFilePath); } catch (err) { log.error(`\x1b[31mError: ${err as Error}\x1b[0m`); + // Ensure the temporary file is deleted even in case of an error + if (fs.existsSync(tempFilePath)) { + fs.unlinkSync(tempFilePath); + } } } diff --git a/packages/gluestack-cli/template/codemods/tailwind-config-transform.ts b/packages/gluestack-cli/template/codemods/tailwind-config-transform.ts index 583b9729..438edaca 100644 --- a/packages/gluestack-cli/template/codemods/tailwind-config-transform.ts +++ b/packages/gluestack-cli/template/codemods/tailwind-config-transform.ts @@ -1,10 +1,26 @@ import { Transform } from 'jscodeshift'; +import fs from 'fs-extra'; const transform: Transform = (file, api, options) => { try { const j = api.jscodeshift; const root = j(file.source); - // Find the tailwind.config.js file + + // Read the options from the file (passed via --optionsFile) + const optionsFile = options.optionsFile; + let externalOptions = { paths: [], projectType: '' }; + + if (optionsFile && fs.existsSync(optionsFile)) { + const fileContent = fs.readFileSync(optionsFile, 'utf-8'); + externalOptions = JSON.parse(fileContent); + } + + const { paths: newPaths } = externalOptions; + + // Ensure options.paths is an array + const pathsArray = Array.isArray(newPaths) ? newPaths : []; + + // Find the tailwind.config.js or tailwind.config.ts file const tailwindConfig = root.find(j.AssignmentExpression, { left: { type: 'MemberExpression', @@ -25,16 +41,35 @@ const transform: Transform = (file, api, options) => { return file.source; // No changes, return original content } // Find the 'content' property - const contentProperty = tailwindConfig.find(j.Property, { + let contentProperty = tailwindConfig.find(j.Property, { key: { name: 'content' }, }); - if (contentProperty.length) { - const contentValueNode = contentProperty.get('value'); - const newPaths = options.paths || []; - contentValueNode.value.elements = newPaths.map((path) => - j.stringLiteral(path) + + if (!contentProperty.length) { + // If the content property doesn't exist, create it + const properties = tailwindConfig.get(0).node.right.properties; + const contentPropertyNode = j.property( + 'init', + j.identifier('content'), + j.arrayExpression([]) // Start with an empty array ); + properties.push(contentPropertyNode); + + // Refetch the content property after adding it + contentProperty = tailwindConfig.find(j.Property, { + key: { name: 'content' }, + }); } + + const contentValueNode = contentProperty.get('value'); + if (contentValueNode.value.type === 'ArrayExpression') { + // Replace the existing elements with the new paths + contentValueNode.value.elements = pathsArray.map((path: string) => + j.stringLiteral(path.replace(/\\/g, '/')) + ); + } + + // handling important property const importantProperty = tailwindConfig.find(j.Property, { key: { name: 'important' }, }); From 31b2627fded73bb641d6a34e7c14b986491aff57 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Tue, 5 Nov 2024 16:32:54 +0530 Subject: [PATCH 68/71] v0.7.16-alpha.0 --- packages/gluestack-cli/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gluestack-cli/package.json b/packages/gluestack-cli/package.json index fd2681c2..057e6d8b 100644 --- a/packages/gluestack-cli/package.json +++ b/packages/gluestack-cli/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for easily adding components from gluestack to your projects.", - "version": "0.7.16", + "version": "0.7.16-alpha.0", "license": "MIT", "main": "dist/index.js", "files": [ From a0e1dd6964d6b23a6aa652e504700ac7254d9d66 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Tue, 5 Nov 2024 16:59:19 +0530 Subject: [PATCH 69/71] v0.7.16-alpha.1 --- packages/gluestack-cli/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gluestack-cli/package.json b/packages/gluestack-cli/package.json index 057e6d8b..708b26fd 100644 --- a/packages/gluestack-cli/package.json +++ b/packages/gluestack-cli/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for easily adding components from gluestack to your projects.", - "version": "0.7.16-alpha.0", + "version": "0.7.16-alpha.1", "license": "MIT", "main": "dist/index.js", "files": [ From 60ffae3cba7a2de66be9b6708818dbd31b1a95db Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Tue, 5 Nov 2024 17:55:58 +0530 Subject: [PATCH 70/71] fix: react-native-cli babel transformer --- .../src/util/config/expo-config-helper.ts | 1 - .../util/config/react-native-config-helper.ts | 16 ++++++++++++---- .../codemods/expo/metro-config-transform.ts | 1 - .../react-native-cli/babel-config-transform.ts | 6 ++---- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/packages/gluestack-cli/src/util/config/expo-config-helper.ts b/packages/gluestack-cli/src/util/config/expo-config-helper.ts index 3f3a9e9e..7d8e2697 100644 --- a/packages/gluestack-cli/src/util/config/expo-config-helper.ts +++ b/packages/gluestack-cli/src/util/config/expo-config-helper.ts @@ -10,7 +10,6 @@ import { } from './config-types'; import { join, relative } from 'path'; import { execSync } from 'child_process'; -import { log } from '@clack/prompts'; import { ensureFilesPromise } from '..'; import { commonInitialization } from '../init'; diff --git a/packages/gluestack-cli/src/util/config/react-native-config-helper.ts b/packages/gluestack-cli/src/util/config/react-native-config-helper.ts index d16e511e..0037a2e3 100644 --- a/packages/gluestack-cli/src/util/config/react-native-config-helper.ts +++ b/packages/gluestack-cli/src/util/config/react-native-config-helper.ts @@ -1,11 +1,10 @@ -import * as path from 'path'; import { generateConfig, getFilePath, pathResolver } from '.'; import { RawConfig, ReactNativeResolvedConfig } from './config-types'; import { ensureFilesPromise, getRelativePath } from '..'; import { config } from '../../config'; import { join } from 'path'; import { execSync } from 'child_process'; -import { log } from '@clack/prompts'; +import os from 'os'; import { commonInitialization } from '../init'; //react-native project type initialization @@ -29,6 +28,15 @@ async function resolvedReactNativePaths( return resolvedReactNativePaths; } +const podInstall = async () => { + const platform = os.platform(); + + if (platform === 'darwin') { + // macOS + execSync('npx pod-install', { stdio: 'inherit' }); + } +}; + //project specific initialization: react-native async function initNatiwindRNApp( resolvedConfig: ReactNativeResolvedConfig, @@ -58,7 +66,7 @@ async function initNatiwindRNApp( ); execSync( - `npx jscodeshift -t ${BabelTransformerPath} ${resolvedConfig.config.babelConfig} --config='${JSON.stringify(resolvedConfig)}'` + `npx jscodeshift -t ${BabelTransformerPath} ${resolvedConfig.config.babelConfig} --tailwindConfigPath=${resolvedConfig.tailwind.config}` ); execSync( `npx jscodeshift -t ${metroTransformerPath} ${resolvedConfig.config.metroConfig}` @@ -72,7 +80,7 @@ async function initNatiwindRNApp( permission ); - execSync('npx pod-install', { stdio: 'inherit' }); + await podInstall(); } catch (err) { throw new Error((err as Error).message); } diff --git a/packages/gluestack-cli/template/codemods/expo/metro-config-transform.ts b/packages/gluestack-cli/template/codemods/expo/metro-config-transform.ts index 1afa61d6..5b6cbbbf 100644 --- a/packages/gluestack-cli/template/codemods/expo/metro-config-transform.ts +++ b/packages/gluestack-cli/template/codemods/expo/metro-config-transform.ts @@ -1,7 +1,6 @@ import { writeFileSync } from 'fs-extra'; import { Transform } from 'jscodeshift'; import { parse, print } from 'recast'; -import { ExpoResolvedConfig } from '../../../src/util/config/config-types'; const transform: Transform = (file, api, options) => { try { diff --git a/packages/gluestack-cli/template/codemods/react-native-cli/babel-config-transform.ts b/packages/gluestack-cli/template/codemods/react-native-cli/babel-config-transform.ts index 09af75a0..f94bf1c7 100644 --- a/packages/gluestack-cli/template/codemods/react-native-cli/babel-config-transform.ts +++ b/packages/gluestack-cli/template/codemods/react-native-cli/babel-config-transform.ts @@ -1,12 +1,10 @@ import { Transform } from 'jscodeshift'; -import { ReactNativeResolvedConfig } from '../../../src/util/config/config-types'; const transform: Transform = (file, api, options) => { try { const j = api.jscodeshift; const root = j(file.source); - const config: ReactNativeResolvedConfig = options.config; - const tailwindConfig = config.tailwind.config; + const tailwindConfig = options.tailwindConfigPath; // fetch tailwind config filenName from resolved path of tailwind.config.js const parts = tailwindConfig.split(/[/\\]/); @@ -107,7 +105,7 @@ const transform: Transform = (file, api, options) => { j.property( 'init', j.stringLiteral('tailwind.config'), - j.stringLiteral('./' + tailwindConfig) + j.stringLiteral('./' + tailwindConfigFileName) ), ]) ), From 58cd8e7396b955e38c372571cf70da216a202aa6 Mon Sep 17 00:00:00 2001 From: Vaibhavi Kolloju Date: Tue, 5 Nov 2024 18:23:09 +0530 Subject: [PATCH 71/71] v0.7.17 --- packages/gluestack-cli/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gluestack-cli/package.json b/packages/gluestack-cli/package.json index fd2681c2..f2afd543 100644 --- a/packages/gluestack-cli/package.json +++ b/packages/gluestack-cli/package.json @@ -10,7 +10,7 @@ "cli" ], "description": "A CLI tool for easily adding components from gluestack to your projects.", - "version": "0.7.16", + "version": "0.7.17", "license": "MIT", "main": "dist/index.js", "files": [