From 610b57cd5b91aaf3b5e21fb314c3f5a5872d57be Mon Sep 17 00:00:00 2001 From: Pascal Klesse <54418919+pascal-klesse@users.noreply.github.com> Date: Wed, 2 Oct 2024 01:04:28 +0200 Subject: [PATCH] Feat/component config (#57) * feat: implement component config * feat: implement component config --------- Co-authored-by: Pascal Klesse --- .github/workflows/build.yml | 6 +- .github/workflows/publish.yml | 6 +- src/commands/components/add.ts | 146 +++++++++++++++++++++++++++------ 3 files changed, 127 insertions(+), 31 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9f3efa5..b0e143c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,9 +12,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Git checkout - uses: actions/checkout@v1 + uses: actions/checkout@v4 - name: Use Node.js 16 - uses: actions/setup-node@v1 + uses: actions/setup-node@v4 with: node-version: 16 - name: Install dependencies @@ -24,7 +24,7 @@ jobs: - name: Build run: npm run build - name: Save build - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 with: name: build path: ./build diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index e29081f..f1b1fd1 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -10,9 +10,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Git checkout - uses: actions/checkout@v1 + uses: actions/checkout@v4 - name: Node 16 - uses: actions/setup-node@v1 + uses: actions/setup-node@v4 with: node-version: 16 - name: NPM install @@ -20,6 +20,6 @@ jobs: - name: Build run: npm run build - name: Publish - uses: JS-DevTools/npm-publish@v1 + uses: JS-DevTools/npm-publish@v3 with: token: ${{ secrets.NPM_TOKEN }} diff --git a/src/commands/components/add.ts b/src/commands/components/add.ts index e85aeab..1c47404 100644 --- a/src/commands/components/add.ts +++ b/src/commands/components/add.ts @@ -1,7 +1,7 @@ import { GluegunCommand } from 'gluegun' import { ExtendedGluegunToolbox } from '../../interfaces/extended-gluegun-toolbox' import * as fs from 'fs' -import * as glob from 'glob'; +import * as glob from 'glob' import * as path from 'path' import axios from 'axios' @@ -12,8 +12,100 @@ const AddComponentCommand: GluegunCommand = { const { parameters } = toolbox const componentName = parameters.first await addComponent(toolbox, componentName) - process.exit(); - return 'add'; + process.exit() + return 'add' + } +} + +async function getConfigForComponent(fileName: string) { + const data = await getConfig() + const name = fileName.split('.').slice(0, -1).join('.') + return data.config[name] || {}; +} + +async function getConfig() { + const githubApiUrl = `https://raw.githubusercontent.com/lenneTech/nuxt-base-components/main/config.json` + const response = await axios.get(githubApiUrl); + + if (response.status === 200) { + return response.data; + } else { + throw new Error(`Fehler beim Abrufen der Konfiguration von GitHub: ${response.statusText}`) + } +} + +async function processConfig(config: any, toolbox: ExtendedGluegunToolbox) { + const {prompt} = toolbox; + + if (config?.npm) { + const npmPackages = config.npm + for (const npmPackage of npmPackages) { + const confirm = await prompt.confirm(`Das npm-Paket ${npmPackage} wird benötigt. Möchten Sie es installieren?`) + + if (confirm) { + await installPackage(npmPackage, toolbox) + } + } + } + + if (config?.composables) { + const composables = config.composables + for (const composable of composables) { + const confirm = await prompt.confirm(`Das composable ${composable} wird benötigt. Möchten Sie es hinzufügen?`) + + if (confirm) { + await copyComposable(composable, toolbox) + } + } + } + + if (config?.components) { + const components = config.components + for (const component of components) { + const confirm = await prompt.confirm(`Die component ${component} wird benötigt. Möchten Sie es hinzufügen?`) + + if (confirm) { + await copyComponent({ name: component + '.vue', type: 'file' }, toolbox) + } + } + } +} + +async function installPackage(packageName: string, toolbox: ExtendedGluegunToolbox) { + const { print, system } = toolbox + const installSpinner = print.spin(`Installiere npm-Paket ${packageName}...`) + await system.run(`npm install ${packageName} --save-exact`) + installSpinner.succeed(`npm-Paket ${packageName} erfolgreich installiert`) +} + +async function copyComposable(composable: string, toolbox: ExtendedGluegunToolbox) { + const { print } = toolbox + const apiUrl = `https://raw.githubusercontent.com/lenneTech/nuxt-base-components/main/composables/${composable}.ts` + const response = await axios.get(apiUrl) + + if (response.status === 200) { + const sourceCode = response.data + const cwd = process.cwd() + let targetDirectory: string + + if (fs.existsSync(path.resolve(cwd, 'composables'))) { + targetDirectory = path.resolve(cwd, 'composables') + } else { + const directories = glob.sync('*/composables', { cwd }) + + if (directories.length > 0) { + targetDirectory = path.join(cwd, directories[0]) + } else { + targetDirectory = cwd + } + } + + const targetPath = path.join(targetDirectory, `${composable}.ts`) + const spinner = print.spin(`Kopiere das Composable ${composable} nach ${targetPath}...`) + fs.writeFileSync(targetPath, sourceCode) + spinner.succeed(`Das Composable ${composable} wurde erfolgreich kopiert nach ${targetPath}`) + } else { + print.error(`Fehler beim Abrufen der Datei von GitHub: ${response.statusText}`) } } @@ -37,28 +129,28 @@ async function addComponent(toolbox: ExtendedGluegunToolbox, componentName: stri const { print, prompt } = toolbox try { - const compSpinner = print.spin('Lade Komponenten Auswahl von GitHub...'); + const compSpinner = print.spin('Lade Komponenten Auswahl von GitHub...') const possibleComponents = await getFileInfo() - compSpinner.succeed('Komponenten Auswahl von GitHub erfolgreich geladen'); + compSpinner.succeed('Komponenten Auswahl von GitHub erfolgreich geladen') if (possibleComponents.length > 0) { - let selectedComponent: string = ''; + let selectedComponent: string = '' if (!componentName) { const response = await prompt.ask({ type: 'select', name: 'componentType', message: 'Welche Komponente möchten Sie hinzufügen:', - choices: possibleComponents, + choices: possibleComponents }) selectedComponent = response.componentType } else { - selectedComponent = componentName + selectedComponent = componentName + '.vue'; } - const selectedFile = possibleComponents.find((e) => e.name === selectedComponent); + const selectedFile = possibleComponents.find((e) => e.name === selectedComponent) if (selectedFile?.type === 'dir') { - print.success(`Das Verzeichnis ${selectedFile.name} wurde ausgewählt.`); + print.success(`Das Verzeichnis ${selectedFile.name} wurde ausgewählt.`) const directoryFiles = await getFileInfo(selectedFile.name) if (directoryFiles.length > 0) { @@ -73,7 +165,7 @@ async function addComponent(toolbox: ExtendedGluegunToolbox, componentName: stri print.error(`Das Verzeichnis ${selectedFile.name} ist leer.`) } } else if (selectedFile?.type === 'file') { - print.success(`Die Komponente ${selectedFile.name} wurde ausgewählt.`); + print.success(`Die Komponente ${selectedFile.name} wurde ausgewählt.`) await copyComponent(selectedFile, toolbox) } } else { @@ -86,13 +178,21 @@ async function addComponent(toolbox: ExtendedGluegunToolbox, componentName: stri async function copyComponent(file: { name: string; type: 'dir' | 'file' }, toolbox: ExtendedGluegunToolbox) { const { print } = toolbox - const apiUrl = `https://raw.githubusercontent.com/lenneTech/nuxt-base-components/main/components/${file.name}`; + const apiUrl = `https://raw.githubusercontent.com/lenneTech/nuxt-base-components/main/components/${file.name}` return new Promise(async (resolve, reject) => { try { - const compSpinner = print.spin(`Lade Komponente ${file.name} von GitHub...`); + const configSpinner = print.spin(`Checken der config für ${file.name}...`) + const config = await getConfigForComponent(file.name) + configSpinner.succeed(`Config für ${file.name} erfolgreich geladen`) + + if (config) { + await processConfig(config, toolbox) + } + + const compSpinner = print.spin(`Lade Komponente ${file.name} von GitHub...`) const response = await axios.get(apiUrl) - compSpinner.succeed(`Komponente ${file.name} erfolgreich von GitHub geladen`); + compSpinner.succeed(`Komponente ${file.name} erfolgreich von GitHub geladen`) if (response.status === 200) { const sourceCode = response.data @@ -102,7 +202,7 @@ async function copyComponent(file: { name: string; type: 'dir' | 'file' }, toolb if (fs.existsSync(path.resolve(cwd, 'components'))) { targetDirectory = path.resolve(cwd, 'components') } else { - const directories = glob.sync('*/components', { cwd }); + const directories = glob.sync('*/components', { cwd }) if (directories.length > 0) { targetDirectory = path.join(cwd, directories[0]) @@ -111,27 +211,23 @@ async function copyComponent(file: { name: string; type: 'dir' | 'file' }, toolb } } - print.info(`Found directory for components: ${targetDirectory}`) - const targetPath = path.join(targetDirectory, `${file.name}`) if (!fs.existsSync(targetDirectory)) { - const targetDirSpinner = print.spin(`Creating target directory...`) + const targetDirSpinner = print.spin(`Erstellen des Zielverzeichnis...`) fs.mkdirSync(targetDirectory, { recursive: true }) - targetDirSpinner.succeed(`Target directory created successfully`) + targetDirSpinner.succeed(); } if (file.type === 'dir') { - const dirName = file.name.split('/')[0]; - const dirPath = path.join(targetDirectory, dirName); + const dirName = file.name.split('/')[0] + const dirPath = path.join(targetDirectory, dirName) if (!fs.existsSync(dirPath)) { - const dirSpinner = print.spin(`Creating directory ${dirName}...`) - fs.mkdirSync(dirPath, { recursive: true }) - dirSpinner.succeed(`Directory ${dirName} created successfully`) + fs.mkdirSync(dirPath, { recursive: true }); } } const spinner = print.spin(`Kopiere die Komponente ${file.name} nach ${targetPath}...`) - fs.writeFileSync(targetPath, sourceCode); + fs.writeFileSync(targetPath, sourceCode) spinner.succeed(`Die Komponente ${file.name} wurde erfolgreich kopiert nach ${targetPath}`) resolve(targetPath) } else {