.editorconfig000066400000000000000000000006401516073125500135400ustar00rootroot00000000000000# EditorConfig helps developers define and maintain consistent # coding styles between different editors and IDEs # editorconfig.org root = true [*] # Change these settings to your own preference indent_style = space indent_size = 4 # We recommend you to keep these unchanged end_of_line = lf charset = utf-8 trim_trailing_whitespace = false insert_final_newline = true [*.md] trim_trailing_whitespace = false .github/000077500000000000000000000000001516073125500124235ustar00rootroot00000000000000.github/workflows/000077500000000000000000000000001516073125500144605ustar00rootroot00000000000000.github/workflows/build.yml000066400000000000000000000016761516073125500163140ustar00rootroot00000000000000# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions name: build on: schedule: - cron: '0 0 1 * *' push: branches: [ master ] pull_request: branches: [ master ] jobs: build: runs-on: ubuntu-latest strategy: matrix: node-version: ['lts/*'] # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ steps: - uses: actions/checkout@v2 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v2 with: node-version: ${{ matrix.node-version }} - run: npm i -g grunt-cli - run: npm install - run: grunt .gitignore000066400000000000000000000003301516073125500130470ustar00rootroot00000000000000/build /node_modules /*.log .idea/workspace.xml .idea/tasks.xml .idea/profiles_settings.xml .idea/inspectionProfiles/Project_Default.xml .idea/inspectionProfiles/profiles_settings.xml node_modules/.yarn-integrity .ncurc.json000066400000000000000000000000521516073125500131430ustar00rootroot00000000000000{ "reject": [ "chalk" ] } .npmignore000066400000000000000000000002331516073125500130600ustar00rootroot00000000000000/.idea /artifacts /build /test /node_modules /*.iml /*.ipr /*.iws /.travis.yml /.scrutinizer.yml /Gruntfile.js /*.lock *.log /corifeus-boot.json /.github .travis.yml000066400000000000000000000014571516073125500132030ustar00rootroot00000000000000language: node_js cache: npm: false node_js: - lts/* before_script: - npm install -g grunt-cli npm env: global: secure: YcRSWYkwc69CxiZ00bQzEbkj2KzYvxxVRovL0tlYiKiK2bffoy25W69wsvGTFhyo3EsBe6RNuKuV9Aq4G3W2G9dAJ3xjB5KDJ/qHdmu/BFqricyo2uKPjO9ug99HwCW9D2eYS9gr5k+Bqq5GJqc17bIoopSK7T9f0AmIWHMgIP0y/8KZnlO0uu+Cg8mmGz9YNQAN4+UYspYyNSQP69/cokp/IvGgLHTo5ulqBHh0DTH5jSzlwlLterFjWAl43meSwHVp8HpBs1D+1Zq8fx2v5C/aGJ/HnN7kcA9Ma/Ct/AnT17vMZOr3G3vc2ypts8VRuKu65XqLTRQXXIy7uM62xNx3e7f8bCr5vavrZKPPuxDO0/EISu7Bmy1EudoizfTxMH9n/Lid8FmxQ48FkD5QKVT/jkXBk55b99L7KWnmRSQK1bRm0ip17bbSPxzUj6roXiWwITCDniSssnMONZjbBEQAPHRw7NsEEPMX8wxRkV4Brda4ce+xz9Knf700RCfB0HhCucFv/2erWrMSLUF+v/Qdznud8r8eEVbsynz5iMiOuOWwh7iHwOZ5qSeOaHh9XDcpgcIq1GmJyzjB2VDkfkPsfJEnlnApgKxpCNIJ8xtvPHkiABwqgsUrsnb5a/ZyxswZSr2+MwCjWXsNT0venzEPze5gp8eFHbamvnueeEc= Gruntfile.js000066400000000000000000000004541516073125500133630ustar00rootroot00000000000000module.exports = (grunt) => { const builder = require(`corifeus-builder`); const loader = new builder.loader(grunt); loader.js({ replacer: { type: 'p3x', npmio: true, }, }); grunt.registerTask('default', builder.config.task.build.js); };LICENSE000066400000000000000000000022701516073125500120710ustar00rootroot00000000000000 @license p3x-verdaccio-cli v2022.4.128 🍶 Verdaccio CLI https://corifeus.com/verdaccio-cli Copyright (c) 2022 Patrik Laszlo / P3X / Corifeus and contributors. MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. README.md000066400000000000000000000120311516073125500123370ustar00rootroot00000000000000[//]: #@corifeus-header [![NPM](https://nodei.co/npm/p3x-verdaccio-cli.png?downloads=true&downloadRank=true)](https://www.npmjs.com/package/p3x-verdaccio-cli/) [![Donate for Corifeus / P3X](https://img.shields.io/badge/Donate-Corifeus-003087.svg)](https://paypal.me/patrikx3) [![Contact Corifeus / P3X](https://img.shields.io/badge/Contact-P3X-ff9900.svg)](https://www.patrikx3.com/en/front/contact) [![Corifeus @ Facebook](https://img.shields.io/badge/Facebook-Corifeus-3b5998.svg)](https://www.facebook.com/corifeus.software) [![Build Status](https://github.com/patrikx3/verdaccio-cli/workflows/build/badge.svg)](https://github.com/patrikx3/verdaccio-cli/actions?query=workflow%3Abuild) [![Uptime Robot ratio (30 days)](https://img.shields.io/uptimerobot/ratio/m780749701-41bcade28c1ea8154eda7cca.svg)](https://stats.uptimerobot.com/9ggnzcWrw) # 🍶 Verdaccio CLI v2022.4.128 **Bugs are evident™ - MATRIX️** ### NodeJS LTS is supported ### Built on NodeJs version ```txt v16.15.0 ``` # Description [//]: #@corifeus-header:end It is that first `p3x-verdaccio-cli` version that is working with the [Verdaccio](https://github.com/verdaccio). Based on https://github.com/verdaccio/verdaccio/issues/343 Of course, with an option eg. `--storage=azure` it could be enabled. ⚠️ **MAKE SURE TO STOP VERDACCIO BEFORE YOU CONTINUE AND MAKE SURE TO BACKUP BEFORE YOU CHANGE ANYTHING, SO THAT YOU COULD REVERT IF SOMETHING IS NOT STATISFYING!!!** ⚠️ **This is only working with the original Sinopia file system storage driver!!!** **For own packages only works without namespaces!** # Show the help ```bash p3x-verdaccio-cli ``` # Routines ## Cache ### Info ```text p3x-verdaccio-cli --config /var/npm/config.yaml cache info ``` #### Output ```text root@server:~# p3x-verdaccio-cli --config /var/npm/config.yaml cache info Please add a flag --confirm and only add this flag after you stopped Verdaccio! Own packages: corifeus-utils, corifeus-builder, corifeus-builder-angular, corifeus-web, corifeus-web-material, p3x-aes-folder, p3x-angular-compile, p3x-html-pdf, p3x-onenote, p3x-ramdisk, p3x-systemd-manager, p3x-tools, p3x-freenom, grunt-p3x-express, corifeus-server, p3x-redis-ui-server, p3x-redis-ui-material, p3x-redis-ui, p3x-verdaccio-cli, p3x-xml2json Own packages count: 20 Total of package count without own packages: 1668 Please add a flag --confirm and only add this flag after you stopped Verdaccio! ``` ### Clean ```bash # first you can try a dry run and give some output info p3x-verdaccio-cli --config /var/npm/config.yaml --dry cache clean # actually clean the cache p3x-verdaccio-cli --config /var/npm/config.yaml cache clean ``` ## Package remove ```bash # first you can try a dry run and give some output info p3x-verdaccio-cli --config /var/npm/config.yaml --dry pkg-rm my-own-pkg # actually it removes a package p3x-verdaccio-cli --config /var/npm/config.yaml pkg-rm my-own-pkg ``` ## Package ### Keep This function removes old versions from Verdaccio and keep the set minimum versions (eg. keep minimum 3 versions and delete the rest). ```bash # first you can try a dry run and give some output info p3x-verdaccio-cli --config /var/npm/config.yaml --dry pkg keep # actually keeps 3 last versions of your all own packages p3x-verdaccio-cli --config /var/npm/config.yaml pkg keep # if you want more versions, use the --min flag, and keep 10 versions for each packages p3x-verdaccio-cli --config /var/npm/config.yaml pkg keep --min 10 ``` ⚠️ **MAKE SURE TO START VERDACCIO AFTER YOU HAVE DONE!!!** [//]: #@corifeus-footer --- 🙏 This is an open-source project. Star this repository, if you like it, or even donate to maintain the servers and the development. Thank you so much! Possible, this server, rarely, is down, please, hang on for 15-30 minutes and the server will be back up. All my domains ([patrikx3.com](https://patrikx3.com) and [corifeus.com](https://corifeus.com)) could have minor errors, since I am developing in my free time. However, it is usually stable. **Note about versioning:** Versions are cut in Major.Minor.Patch schema. Major is always the current year. Minor is either 4 (January - June) or 10 (July - December). Patch is incremental by every build. If there is a breaking change, it should be noted in the readme. --- [**P3X-VERDACCIO-CLI**](https://corifeus.com/verdaccio-cli) Build v2022.4.128 [![Donate for Corifeus / P3X](https://img.shields.io/badge/Donate-Corifeus-003087.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=QZVM4V6HVZJW6) [![Contact Corifeus / P3X](https://img.shields.io/badge/Contact-P3X-ff9900.svg)](https://www.patrikx3.com/en/front/contact) [![Like Corifeus @ Facebook](https://img.shields.io/badge/LIKE-Corifeus-3b5998.svg)](https://www.facebook.com/corifeus.software) ## P3X Sponsor [IntelliJ - The most intelligent Java IDE](https://www.jetbrains.com/?from=patrikx3) [![JetBrains](https://cdn.corifeus.com/assets/svg/jetbrains-logo.svg)](https://www.jetbrains.com/?from=patrikx3) [//]: #@corifeus-footer:end bin/000077500000000000000000000000001516073125500116335ustar00rootroot00000000000000bin/p3x-verdaccio-cli.js000077500000000000000000000003441516073125500154110ustar00rootroot00000000000000#!/usr/bin/env node if (!require('fs').existsSync(`${__dirname}/../node_modules`)) { require('child_process').execSync(`cd ${__dirname}/.. && npm install --only=prod`, { stdio: 'inherit' }); } require('../src') package.json000066400000000000000000000023401516073125500133500ustar00rootroot00000000000000{ "name": "p3x-verdaccio-cli", "version": "2022.4.128", "corifeus": { "prefix": "p3x-", "publish": true, "type": "p3x", "code": "Sake", "nodejs": "v16.15.0", "opencollective": false, "reponame": "verdaccio-cli", "build": true }, "bin": { "p3x-verdaccio-cli": "bin/p3x-verdaccio-cli.js" }, "license": "MIT", "description": "🍶 Verdaccio CLI", "main": "src/index.js", "directories": { "test": "test" }, "scripts": { "test": "grunt" }, "repository": { "type": "git", "url": "git+https://github.com/patrikx3/verdaccio-cli.git" }, "keywords": [ "verdaccio", "cli" ], "author": "Patrik Laszlo ", "bugs": { "url": "https://github.com/patrikx3/verdaccio-cli/issues" }, "homepage": "https://corifeus.com/verdaccio-cli", "devDependencies": { "corifeus-builder": "^2022.4.130" }, "dependencies": { "chalk": "^4.1.2", "cli-table": "^0.3.11", "commander": "^9.3.0", "fs-extra": "^10.1.0", "js-yaml": "^4.1.0" }, "engines": { "node": ">=12.13.0" } }src/000077500000000000000000000000001516073125500116525ustar00rootroot00000000000000src/index.js000066400000000000000000000044321516073125500133220ustar00rootroot00000000000000const { program } = require('commander') const lib = require('./lib') const pkg = lib.pkg const start = async () => { program .version(pkg.version) .option('-c, --config ', 'This is required to provide the Verdaccio configuration.') .option('-d, --dry', 'Do not actually clean the cache, just print some info.') program .command('cache ') .description(`The can be info or clean.`) .option('--confirm', 'Only use this flag, when you have stopped Verdaccio at first.') .action(async (routine, options) => { try { await require('./routine/cache').cache(routine, options); } catch (e) { console.error(e) } }) program .command('package') .description(`Please use instead of package => pkg.`) .action(async (options) => { console.info("Please use instead of package => pkg.") }) const pkgKeepMinimum = 3 program .command('pkg ') .description(`The can be info or keep.`) .option('--confirm', 'Only use this flag, when you have stopped Verdaccio at first.') .option('-m, --min ', 'The default and minimum is ' + pkgKeepMinimum, parseInt) .action(async (routine, options) => { try { await require('./routine/package').default({minimum: pkgKeepMinimum}, routine, options); } catch (e) { console.error(e) } }) program .command('pkg-rm ') .description(`The is a name we want to remove.`) .option('--confirm', 'Only use this flag, when you have stopped Verdaccio at first.') .action(async (pkgName, options) => { try { await require('./routine/package').remove(pkgName, options); } catch (e) { console.error(e) } }) program.parse(process.argv); if (!process.argv.slice(2).length) { program.outputHelp(); } else if (program.opts().config === undefined) { return console.error(`The ${pkg.name} program's first argument should be like '--config=/verdaccio/path/config.yaml' and should present.`) } } start(); src/lib.js000066400000000000000000000023401516073125500127550ustar00rootroot00000000000000const pkg = require('../package') const fs = require('fs').promises const path = require('path') const chalk = require('chalk') const parseConfig = async (opts) => { const yaml = require('js-yaml') //console.warn(opts) const yamlString = (await fs.readFile(opts.config)).toString() const yamlConfig = yaml.load(yamlString) //console.warn(yamlConfig) return yamlConfig } module.exports.defaults = async () => { const { program } = require('commander') //console.warn(options) const configPath = path.dirname(program.opts().config) const config = await parseConfig({ config: program.opts().config }) const storagePath = path.resolve(configPath, config.storage) const dbPath = path.resolve(storagePath, '.verdaccio-db.json'); const db = require(dbPath) return { configPath: configPath, config: config, storagePath: storagePath, db: db, dbPath: dbPath, } } module.exports.confirmInfo = (options) => { if (options.confirm !== true) { console.info(chalk.yellow(` Please add a flag --confirm and only add this flag after you stopped Verdaccio! `)) } } module.exports.parseConfig = parseConfig module.exports.pkg = pkg src/routine/000077500000000000000000000000001516073125500133375ustar00rootroot00000000000000src/routine/cache.js000066400000000000000000000044651516073125500147510ustar00rootroot00000000000000const fs = require('fs').promises const path = require('path') const fsExtra = require('fs-extra') const lib = require('../lib') const availableCacheRoutine = [ 'clean', 'info', ] const chalk = require('chalk') const cache = async (routine, options) => { const { program } = require('commander') if (!availableCacheRoutine.includes(routine)) { return console.error(`The cache is not available '${routine}', the available routines are ${availableCacheRoutine.join(', ')}.`) } const defaults = await lib.defaults(); const packageFolders = await fs.readdir(defaults.storagePath) //console.warn(packageFolders) const packageFoldersWithoutOwn = [] const packageFolderPathStatAwaitable = [] for (let packageFolderPath of packageFolders) { packageFolderPathStatAwaitable.push( fs.stat(path.resolve(defaults.storagePath, packageFolderPath)) ) } const packageFolderPathStatAwaitableResult = await Promise.all(packageFolderPathStatAwaitable) for (let statIndex in packageFolderPathStatAwaitableResult) { const stat = packageFolderPathStatAwaitableResult[statIndex] //console.warn(stat) const packagePath = packageFolders[statIndex] if (stat.isDirectory() && !defaults.db.list.includes(packagePath)) { packageFoldersWithoutOwn.push(packagePath) } } if (options.confirm !== true) { console.info('Please add a flag --confirm and only add this flag after you stopped Verdaccio!') } if (program.opts().dry === true || routine === 'info' || options.confirm !== true) { console.info(` Own packages: ${defaults.db.list.join(', ')} Own packages count: ${defaults.db.list.length} Total of package count without own packages: ${packageFoldersWithoutOwn.length} `) lib.confirmInfo(options) return } const removablePathAwaitable = [] for (let packagePath of packageFoldersWithoutOwn) { removablePathAwaitable.push( fsExtra.remove(path.resolve(defaults.storagePath, packagePath)) ) } await Promise.all(removablePathAwaitable) console.info('Removed all cached packages and kept all own packages.') //console.warn(packageFoldersWithoutOwn.length, packageFolders.length) } module.exports.cache = cache src/routine/package.js000066400000000000000000000153521516073125500152760ustar00rootroot00000000000000const fs = require('fs').promises const fsExtra = require('fs-extra') const path = require('path') const lib = require('../lib') const availablePackageRoutine = [ 'keep', ] const Table = require('cli-table'); const chalk = require('chalk') const defaultFn = async (settings, routine, options) => { const {root} = settings; const { program } = require('commander') if (!availablePackageRoutine.includes(routine)) { return console.error(`The '${routine}' is not available , the available routines are ${availablePackageRoutine.join(', ')}.`) } const {minimum} = settings if (options.min === undefined) { options.min = minimum } if (isNaN(options.min)) { console.warn(`The options --min variable be a number.`) return } if (options.min < minimum) { console.warn(`The options --min variable number must be at least ${minimum}.`) return } const defaults = await lib.defaults(); const db = defaults.db const awaitablePackages = [] for (let dbItem of db.list) { awaitablePackages.push( fs.readFile(path.resolve(defaults.storagePath, `${dbItem}/package.json`)) ) } let foundBuffers try { foundBuffers = await Promise.all(awaitablePackages); } catch (e) { if (e.code === 'ENOENT') { const pkgName = path.basename(path.dirname(e.path)) console.warn(chalk.yellow(` It looks like the package '${pkgName}' present is the db, but is deleted from file system. To fix this error, please do this: ${program._name} --config ${program.opts().config} pkg-rm ${pkgName} `)) return } else { throw e } } const pkgRegistry = {} for (let dbItemIndex in db.list) { const dbItem = db.list[dbItemIndex] const pkgBuffer = foundBuffers[dbItemIndex] pkgRegistry[dbItem] = JSON.parse(pkgBuffer.toString()); } if (program.opts().dry === true || routine === 'info' || options.confirm !== true) { console.info(` Own packages: ${defaults.db.list.join(', ')} Own packages count: ${defaults.db.list.length} Will keep last versions: ${options.min} `) const table = new Table({ head: ['Package', 'Version count'] }); for (let pkgName of Object.keys(pkgRegistry)) { table.push( [pkgName, Object.keys(pkgRegistry[pkgName].time).length - 2] ) } console.info(table.toString()) lib.confirmInfo(options) return } const table = new Table({ head: ['Package', 'Kept versions'] }); for await(let pkgName of Object.keys(pkgRegistry)) { const pkgNamed = pkgRegistry[pkgName] if (!pkgNamed.hasOwnProperty('_distfiles')) { pkgNamed['__distfiles'] = {} } if (!pkgNamed.hasOwnProperty('_attachments')) { pkgNamed['_attachments'] = {} } const versions = Object.assign({}, pkgNamed.time) delete versions['created']; delete versions['modified'] Object.keys(versions).forEach(versionKey => { versions[versionKey] = new Date(versions[versionKey]) }) // the sorted shows the order array => by time let sortedVersions = {} sortedVersions = Object.keys(versions).sort((a, b) => { return versions[b] - versions[a] }) const createVersionFile = (version) => { return `${pkgName}/${pkgName}-${version}.tgz` } let minBuffer = 0 for await(let version of sortedVersions) { minBuffer++ if (minBuffer <= options.min) { continue } /* pkg.versions = version as key pkg.time = versions as key, but there is modified and created pkg._distfiles => delete key pkg._distfiles[pkg-name-verions.tgz] pkg._attachments => delete key pkg._attachments[pkg-name-versions.tgz] */ const versionName = createVersionFile(version) delete pkgNamed.versions[version] delete pkgNamed.time[version] delete pkgNamed._distfiles[versionName] delete pkgNamed._attachments[versionName] await fsExtra.remove(path.resolve(defaults.storagePath, versionName)) } for await (let pkgVersionKey of Object.keys(pkgNamed.versions)) { if (!pkgNamed.time.hasOwnProperty(pkgVersionKey)) { delete pkgNamed.versions[pkgVersionKey] const versionName = createVersionFile(pkgVersionKey) delete pkgNamed._distfiles[pkgVersionKey] delete pkgNamed._attachments[pkgVersionKey] await fsExtra.remove(path.resolve(defaults.storagePath, versionName)) } } const removeFileNamed = async (prop) => { let versionsNamed = Object.keys(pkgNamed[prop]) for await(let versionName of versionsNamed) { let version = versionName.slice(pkgName.length + 1) version = version.slice(0, -4) if (!pkgNamed.time.hasOwnProperty(version)) { delete pkgNamed.versions[version] delete pkgNamed._distfiles[versionName] delete pkgNamed._attachments[versionName] await fsExtra.remove(path.resolve(defaults.storagePath, versionName)) } } } await removeFileNamed('_distfiles') await removeFileNamed('_attachments') table.push( [pkgName, `${Object.keys(pkgNamed.time).length - 2}`] ) //console.info(sortedVersions) //console.log(Object.keys(sortedVersions).length) //console.info() await fs.writeFile(path.resolve(defaults.storagePath, `${pkgName}/package.json`), JSON.stringify(pkgNamed, null, 4)) } console.info(table.toString()) } const remove = async (pkgName, options) => { const { program } = require('commander') const defaults = await lib.defaults(); const db = defaults.db if (!db.list.includes(pkgName)) { console.warn(` This package '${pkgName}' is not present in the db! The available db packages: ${db.list.join(", ")} `) return } if (program.opts().dry === true || options.confirm !== true) { console.info(`Could remove package: ${pkgName}`) lib.confirmInfo(options) return; } await fsExtra.remove(path.resolve(defaults.storagePath, pkgName)) db.list = db.list.filter(dbItem => dbItem !== pkgName) await fs.writeFile(defaults.dbPath, JSON.stringify(db)) console.info(`Removed package: ${pkgName}`) } module.exports.default = defaultFn module.exports.remove = remove test/000077500000000000000000000000001516073125500120425ustar00rootroot00000000000000test/cli/000077500000000000000000000000001516073125500126115ustar00rootroot00000000000000test/cli/cache-clean000077500000000000000000000001651516073125500146640ustar00rootroot00000000000000#!/usr/bin/env bash ./bin/p3x-verdaccio-cli.js --config=/home/patrikx3/Desktop/Downloads/npm/config.yaml cache clean test/cli/cache-clean-dry000077500000000000000000000001711516073125500154550ustar00rootroot00000000000000#!/usr/bin/env bash ./bin/p3x-verdaccio-cli.js --config=/home/patrikx3/Desktop/Downloads/npm/config.yaml -d cache clean verdaccio-cli.iml000066400000000000000000000005171516073125500142750ustar00rootroot00000000000000