diff --git a/artisan.js b/artisan.js index 9a3a81f..0afdde5 100644 --- a/artisan.js +++ b/artisan.js @@ -3,5 +3,9 @@ import { Exec } from '@athenna/common' Exec.artisan('./bin/artisan.js', { - nodeOptions: ['--enable-source-maps', '--import=@athenna/tsconfig'], + nodeOptions: [ + '--no-warnings', + '--enable-source-maps', + '--import=@athenna/tsconfig', + ], }) diff --git a/bin/.athennarc.prod.json b/bin/.athennarc.prod.json index b554804..8275bae 100644 --- a/bin/.athennarc.prod.json +++ b/bin/.athennarc.prod.json @@ -1,9 +1,8 @@ { - "providers": [ - "@athenna/core/providers/CoreProvider" - ], + "providers": ["@athenna/core/providers/CoreProvider"], "commands": { - "new": "#src/commands/new.command" + "new": "#src/commands/new.command", + "version": "#src/commands/version.command" }, "templates": { "artisan": "templates/artisan.edge" diff --git a/package-lock.json b/package-lock.json index 458d062..8daa3f1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,21 +1,21 @@ { "name": "@athenna/cli", - "version": "4.14.0", + "version": "4.15.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@athenna/cli", - "version": "4.14.0", + "version": "4.15.0", "license": "MIT", "dependencies": { - "@athenna/artisan": "^4.40.0", - "@athenna/common": "^4.35.0", - "@athenna/config": "^4.19.0", - "@athenna/core": "^4.34.0", - "@athenna/ioc": "^4.18.0", - "@athenna/logger": "^4.18.0", - "@athenna/view": "^4.20.0", + "@athenna/artisan": "^4.41.0", + "@athenna/common": "^4.36.0", + "@athenna/config": "^4.20.0", + "@athenna/core": "^4.36.0", + "@athenna/ioc": "^4.19.0", + "@athenna/logger": "^4.19.0", + "@athenna/view": "^4.21.0", "reflect-metadata": "^0.2.1", "source-map-support": "^0.5.21" }, @@ -92,9 +92,9 @@ "dev": true }, "node_modules/@athenna/artisan": { - "version": "4.40.0", - "resolved": "https://registry.npmjs.org/@athenna/artisan/-/artisan-4.40.0.tgz", - "integrity": "sha512-y0JQzRDu6egmU6gkw3qSjVR2VdUVoGiL36S5BUBsejlrMAevl2dSQHZbozcsuzQlEqY9PgL2GPjsjRfdiF9cig==", + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/@athenna/artisan/-/artisan-4.41.0.tgz", + "integrity": "sha512-EaP0JfvKWwin+ZXnkz8zv4L3et43Bn1AJ65j2fqmcu/cO9fnnAB6BZKMrqJ9w/9yHQK2dYn06lnbhDYs/P8jPg==", "dependencies": { "chalk-rainbow": "^1.0.0", "cli-boxes": "^3.0.0", @@ -111,9 +111,9 @@ } }, "node_modules/@athenna/common": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@athenna/common/-/common-4.35.0.tgz", - "integrity": "sha512-f5JRdrjdozbtHjG0YgqVLXv6fjmss7PKAQWeyqGLg4dpGmheZ19xXYONZYf3ng6d0k2+YQ7IjLzGmfwSsrO+wA==", + "version": "4.36.0", + "resolved": "https://registry.npmjs.org/@athenna/common/-/common-4.36.0.tgz", + "integrity": "sha512-3dPZqHQD5xb9GZfwHqDsVc33sNl6IL0VtXJUybGEYQkWwfZ+nb03Wpxyw3jBr+rZWS6bOqwnWpKTU0Ih93v5Sg==", "dependencies": { "@fastify/formbody": "^7.4.0", "bytes": "^3.1.2", @@ -123,12 +123,12 @@ "collect.js": "^4.36.1", "csv-parser": "^3.0.0", "execa": "^8.0.1", - "fastify": "^4.26.1", + "fastify": "^4.26.2", "got": "^12.6.1", "http-status-codes": "^2.2.0", "is-wsl": "^2.2.0", "js-yaml": "^4.1.0", - "json-2-csv": "^5.0.1", + "json-2-csv": "^5.1.0", "kind-of": "^6.0.3", "lodash": "^4.17.21", "mime-types": "^2.1.35", @@ -163,11 +163,11 @@ } }, "node_modules/@athenna/config": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@athenna/config/-/config-4.19.0.tgz", - "integrity": "sha512-RC6gqSIuOaIvMgdhlTaZqgsraJgffx/SgLPUX0ARkJuGHA/R0Tcw5iqtNu6GVfBVRjqSUe1BlP6pi6FXjxSfpg==", + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@athenna/config/-/config-4.20.0.tgz", + "integrity": "sha512-XUdK74o1iG5zX8tcIp+/+ZBpik6Etz1pjeWRuAkez2WxW35jynLHHxyRnNVwPEfO9dcZG4jAvrKLPi48nnghpw==", "dependencies": { - "dotenv": "^16.4.1", + "dotenv": "^16.4.3", "magicast": "^0.3.3", "syntax-error": "^1.4.0" }, @@ -176,9 +176,9 @@ } }, "node_modules/@athenna/core": { - "version": "4.34.0", - "resolved": "https://registry.npmjs.org/@athenna/core/-/core-4.34.0.tgz", - "integrity": "sha512-ZtknXHLIJcdd2XNhnxBZyd/v5++Z3nCTQ5+ckHzb0joRr99KXgvcPvz4bczm/a+7vgNHNZCBucSd6XjaabwUPQ==", + "version": "4.36.0", + "resolved": "https://registry.npmjs.org/@athenna/core/-/core-4.36.0.tgz", + "integrity": "sha512-55/9gVYh0H2Px0NUFyqaFVBFJVvVAZP1L/1Qp6DA9cu5X5syN9PE5Roy9hYWcfk0o8vLQPqfNDVWTTm0vzFPCQ==", "dependencies": { "pretty-repl": "^3.1.2", "semver": "^7.6.0" @@ -188,9 +188,9 @@ } }, "node_modules/@athenna/ioc": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@athenna/ioc/-/ioc-4.18.0.tgz", - "integrity": "sha512-Ocz7Miaj5dvtnp66brol9Bf6vU97XaBfeXP+RfQtzSyyQs70nSIvCmIXK4oAya15OqHFpqJtR6JXikkQuOVIXw==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@athenna/ioc/-/ioc-4.19.0.tgz", + "integrity": "sha512-nmSyzl51AZ2Y3agcA0iGdLyxZtGpVJ4PBcevHyvGiuKHcreeO3j/BLTmIjM/3lCc0myHzsJeOn2uK2VR8eNfgQ==", "dependencies": { "awilix": "^7.0.3" }, @@ -199,13 +199,13 @@ } }, "node_modules/@athenna/logger": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/@athenna/logger/-/logger-4.18.0.tgz", - "integrity": "sha512-mUGqj5Guh6ZdYflijGAdnn6Zrse2I7SG9fj5jMxSdrQ3hFMCGIgpWIk/ctXCGhPnsHlrVfAmEJeqnCxbtaytZQ==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@athenna/logger/-/logger-4.19.0.tgz", + "integrity": "sha512-LopEIP0GResAfGXkDW8KL7c0JkmK0ZPcjJShYsB6XJDWrbv6QPA9Z+1oPc3odmf53BVCLNQ5K5hT4rbdyl9tqg==", "dependencies": { - "@aws-lambda-powertools/logger": "^1.18.0", + "@aws-lambda-powertools/logger": "^1.18.1", "cls-rtracer": "^2.6.3", - "telegraf": "^4.15.3" + "telegraf": "^4.16.1" }, "engines": { "node": ">=20.0.0" @@ -249,9 +249,9 @@ "dev": true }, "node_modules/@athenna/view": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/@athenna/view/-/view-4.20.0.tgz", - "integrity": "sha512-eAoCPn53GM5zGU9lY0rTNnv8PTSmYNMauy1w9/8BE0OAuedN0a0qVt2W1E1m9IJDsYd29dmV/K63xL6fOR8Ydw==", + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/@athenna/view/-/view-4.21.0.tgz", + "integrity": "sha512-p7ZTRwlUzCvYR+ovwZiNjmI4c+xwWHXUcAiOk3J40dBJTyoKSMuxT2mCYxVYnu0thiu8Eby+U0udF77bWKDU9g==", "dependencies": { "edge.js": "^6.0.1" }, @@ -260,16 +260,16 @@ } }, "node_modules/@aws-lambda-powertools/commons": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/@aws-lambda-powertools/commons/-/commons-1.18.0.tgz", - "integrity": "sha512-oSnST8Wr3WZcT/FgCUzZYUFB+qYHWMAKS0GhWbUqHZMr7I5F75jq/JbeUUF16ShOMGgnEzs5oJjizBYVTI6Oww==" + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/@aws-lambda-powertools/commons/-/commons-1.18.1.tgz", + "integrity": "sha512-gFRgQ2GJDghKvf+fXvT0kQVftgOT05W+hCa7RkfZj6HSjVAO+9DZZeJL3JK1HcsLAjWRj7W9ra0/MqB3Abf+PQ==" }, "node_modules/@aws-lambda-powertools/logger": { - "version": "1.18.0", - "resolved": "https://registry.npmjs.org/@aws-lambda-powertools/logger/-/logger-1.18.0.tgz", - "integrity": "sha512-oB4FPMYNPjME6xsDfm7rxRBHwaH0dQl+bmO9cDbRfiCsZfQxKtTiSvROGt6AvRo+5rhPZyCdn5eAHqCJ4f5tVQ==", + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/@aws-lambda-powertools/logger/-/logger-1.18.1.tgz", + "integrity": "sha512-GsSMqaFXCSz+llSOn2CVNMoN+j/jNsS6JP2Opy9myU0tvg7PeuU3+rN24vKyibUwpxM466IzWFBSJkYdm0bqVw==", "dependencies": { - "@aws-lambda-powertools/commons": "^1.18.0", + "@aws-lambda-powertools/commons": "^1.18.1", "lodash.merge": "^4.6.2" }, "peerDependencies": { @@ -1338,9 +1338,9 @@ } }, "node_modules/@telegraf/types": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/@telegraf/types/-/types-6.9.1.tgz", - "integrity": "sha512-bzqwhicZq401T0e09tu8b1KvGfJObPmzKU/iKCT5V466AsAZZWQrBYQ5edbmD1VZuHLEwopoOVY5wPP4HaLtug==" + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@telegraf/types/-/types-7.1.0.tgz", + "integrity": "sha512-kGevOIbpMcIlCDeorKGpwZmdH7kHbqlk/Yj6dEpJMKEQw5lk0KVQY0OLXaCswy8GqlIVLd5625OB+rAntP9xVw==" }, "node_modules/@tsconfig/node10": { "version": "1.0.9", @@ -3116,9 +3116,9 @@ } }, "node_modules/deeks": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/deeks/-/deeks-3.0.2.tgz", - "integrity": "sha512-c6OmjIygIB/avwXwEQOiODS+nw6fEX4cvOdDMqdL7dt3dicV/xykAJ9AeVc/8/JTVQDuacjRc9KCMmXafL1Y4A==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/deeks/-/deeks-3.1.0.tgz", + "integrity": "sha512-e7oWH1LzIdv/prMQ7pmlDlaVoL64glqzvNgkgQNgyec9ORPHrT2jaOqMtRyqJuwWjtfb6v+2rk9pmaHj+F137A==", "engines": { "node": ">= 16" } @@ -3232,9 +3232,9 @@ } }, "node_modules/doc-path": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/doc-path/-/doc-path-4.0.2.tgz", - "integrity": "sha512-OqZEk7EM1aP3JpO+mq0pv1msEJWrzZVXu4q3YjEYJKc+Wt3/chac4KJdaGueK5IGemOwfptrLctG9I8xkb59qQ==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/doc-path/-/doc-path-4.1.1.tgz", + "integrity": "sha512-h1ErTglQAVv2gCnOpD3sFS6uolDbOKHDU1BZq+Kl3npPqroU3dYL42lUgMfd5UimlwtRgp7C9dLGwqQ5D2HYgQ==", "engines": { "node": ">=16" } @@ -3261,14 +3261,14 @@ } }, "node_modules/dotenv": { - "version": "16.4.1", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.1.tgz", - "integrity": "sha512-CjA3y+Dr3FyFDOAMnxZEGtnW9KBR2M0JvvUtXNW+dYJL5ROWxP9DUHCwgFqpMk0OXCc0ljhaNTr2w/kutYIcHQ==", + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", "engines": { "node": ">=12" }, "funding": { - "url": "https://github.com/motdotla/dotenv?sponsor=1" + "url": "https://dotenvx.com" } }, "node_modules/eastasianwidth": { @@ -5890,12 +5890,12 @@ } }, "node_modules/json-2-csv": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-2-csv/-/json-2-csv-5.0.1.tgz", - "integrity": "sha512-rP9ChyMskS0angbvFdQ43SwEe72mEvqcY1/V2OeukQWxtlreUuZWhMlTdWjtd4L6kJxq+HPFTI06yqLvZiEVIA==", + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/json-2-csv/-/json-2-csv-5.5.1.tgz", + "integrity": "sha512-KgAtAXTQopRwe90gh8SgjRSxgt9bUWbGAPMo9W0TZLA8SqiQH7khtagFfeEUjG3NBPwJu/+9uX5pMvunKaPvrQ==", "dependencies": { - "deeks": "3.0.2", - "doc-path": "4.0.2" + "deeks": "3.1.0", + "doc-path": "4.1.1" }, "engines": { "node": ">= 16" @@ -8305,15 +8305,15 @@ } }, "node_modules/telegraf": { - "version": "4.15.3", - "resolved": "https://registry.npmjs.org/telegraf/-/telegraf-4.15.3.tgz", - "integrity": "sha512-pm2ZQAisd0YlUvnq6xdymDfoQR++8wTalw0nfw7Tjy0va+V/0HaBLzM8kMNid8pbbt7GHTU29lEyA5CAAr8AqA==", + "version": "4.16.3", + "resolved": "https://registry.npmjs.org/telegraf/-/telegraf-4.16.3.tgz", + "integrity": "sha512-yjEu2NwkHlXu0OARWoNhJlIjX09dRktiMQFsM678BAH/PEPVwctzL67+tvXqLCRQQvm3SDtki2saGO9hLlz68w==", "dependencies": { - "@telegraf/types": "^6.9.1", + "@telegraf/types": "^7.1.0", "abort-controller": "^3.0.0", "debug": "^4.3.4", "mri": "^1.2.0", - "node-fetch": "^2.6.8", + "node-fetch": "^2.7.0", "p-timeout": "^4.1.0", "safe-compare": "^1.1.4", "sandwich-stream": "^2.0.2" diff --git a/package.json b/package.json index 5d217ba..5bc17fc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@athenna/cli", - "version": "4.14.0", + "version": "4.15.0", "description": "Athenna CLI to create new Athenna projects.", "license": "MIT", "author": "João Lenon ", @@ -49,13 +49,13 @@ "#tests": "./tests/index.js" }, "dependencies": { - "@athenna/artisan": "^4.40.0", - "@athenna/common": "^4.35.0", - "@athenna/config": "^4.19.0", - "@athenna/core": "^4.34.0", - "@athenna/ioc": "^4.18.0", - "@athenna/logger": "^4.18.0", - "@athenna/view": "^4.20.0", + "@athenna/artisan": "^4.41.0", + "@athenna/common": "^4.36.0", + "@athenna/config": "^4.20.0", + "@athenna/core": "^4.36.0", + "@athenna/ioc": "^4.19.0", + "@athenna/logger": "^4.19.0", + "@athenna/view": "^4.21.0", "reflect-metadata": "^0.2.1", "source-map-support": "^0.5.21" }, @@ -186,7 +186,14 @@ "path": "@athenna/core/commands/InstallCommand", "registry": "npm" }, - "new": "#src/commands/new.command" + "new": { + "path": "#src/commands/new.command", + "loadApp": true + }, + "version": { + "path": "#src/commands/version.command", + "loadApp": true + } }, "templates": { "artisan": "templates/artisan.edge", diff --git a/src/commands/version.command.ts b/src/commands/version.command.ts new file mode 100644 index 0000000..dcf6080 --- /dev/null +++ b/src/commands/version.command.ts @@ -0,0 +1,77 @@ +import { Exec, HttpClient } from '@athenna/common' +import { Argument, BaseCommand } from '@athenna/artisan' +import { IGNORE_REPOS } from '#src/constants/ignorerepos' + +export class VersionCommand extends BaseCommand { + @Argument({ + required: false, + description: 'Specific Athenna package to discover version of.', + }) + private pkg: string + + public static signature(): string { + return 'version' + } + + public static description(): string { + return 'Retrieve the version of all Athenna packages or from single one.' + } + + public async handle(): Promise { + this.logger.simple('({bold,green} [ LIST VERSION ])\n') + + const pkgs = await this.getPkgNames() + const table = await this.getTableVersionFor(...pkgs) + + table.render() + } + + public async getPkgNames() { + if (this.pkg) { + return [this.pkg] + } + + const repositories = await HttpClient.builder() + .prefixUrl('https://api.github.com') + .header('Accept', 'application/vnd.github+json') + .header('X-GitHub-Api-Version', '2022-11-28') + .get('/orgs/AthennaIO/repos') + .json() + + return repositories.map(repository => repository.name) + } + + public async getTableVersionFor(...pkgs: string[]) { + const table = this.logger.table().head('Package', 'Version') + + await Exec.concurrently(pkgs, async pkg => { + if (IGNORE_REPOS.includes(pkg)) { + return + } + + const { name: version } = await HttpClient.builder() + .prefixUrl('https://api.github.com') + .resolveBodyOnly(true) + .throwHttpErrors(false) + .header('Accept', 'application/vnd.github+json') + .header('X-GitHub-Api-Version', '2022-11-28') + .get(`/repos/AthennaIO/${pkg}/releases/latest`) + .json() + + if (!version) { + this.logger.error( + `The repository ${pkg} could not be found in AthennaIO GitHub organization`, + ) + + return + } + + table.row([ + this.paint.yellow(`@athenna/${pkg.toLowerCase()}`), + this.paint.yellow(version), + ]) + }) + + return table + } +} diff --git a/src/constants/ignorerepos.ts b/src/constants/ignorerepos.ts new file mode 100644 index 0000000..5a74fc4 --- /dev/null +++ b/src/constants/ignorerepos.ts @@ -0,0 +1 @@ +export const IGNORE_REPOS = ['Docs', 'Template', 'AthennaIO', 'Benchmarks'] diff --git a/tests/e2e/version.command.test.ts b/tests/e2e/version.command.test.ts new file mode 100644 index 0000000..39fcca6 --- /dev/null +++ b/tests/e2e/version.command.test.ts @@ -0,0 +1,31 @@ +import { Test, type Context } from '@athenna/test' +import { BaseConsoleTest } from '@athenna/core/testing/BaseConsoleTest' + +export default class VersionCommandTest extends BaseConsoleTest { + @Test() + public async shouldBeAbleToListAllAthennaRepositoriesVersion({ command }: Context) { + const output = await command.run('version') + + output.assertSucceeded() + output.assertLogged('@athenna/artisan') + output.assertLogged('@athenna/core') + output.assertLogged('@athenna/cli') + output.assertLogged('@athenna/database') + } + + @Test() + public async shouldBeAbleToListOneSingleAthennaRepositoryVersion({ command }: Context) { + const output = await command.run('version artisan') + + output.assertSucceeded() + output.assertLogged('@athenna/artisan') + } + + @Test() + public async shouldThrowErrorWhenRepositoryDoesNotExist({ command }: Context) { + const output = await command.run('version not-found') + + output.assertSucceeded() + output.assertLogged('The repository not-found could not be found in AthennaIO GitHub organization') + } +}