From b505dda2a6b2115eded91c5e5b9088458977d324 Mon Sep 17 00:00:00 2001 From: korridor <26689068+korridor@users.noreply.github.com> Date: Mon, 4 Mar 2024 18:42:52 +0100 Subject: [PATCH] Added extension system --- .env.example | 2 + .gitignore | 5 +- app/Http/Controllers/Web/HomeController.php | 20 + composer.json | 13 +- composer.lock | 680 +++++++++++++++++-- config/modules.php | 234 +++++++ docker-compose.yml | 2 + routes/web.php | 11 +- tests/Unit/Endpoint/Web/HomeEndpointTest.php | 34 + vite-module-loader.js | 45 ++ 10 files changed, 984 insertions(+), 62 deletions(-) create mode 100644 app/Http/Controllers/Web/HomeController.php create mode 100644 config/modules.php create mode 100644 tests/Unit/Endpoint/Web/HomeEndpointTest.php create mode 100644 vite-module-loader.js diff --git a/.env.example b/.env.example index abf225b1..3dadafcb 100644 --- a/.env.example +++ b/.env.example @@ -73,3 +73,5 @@ VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" NGINX_HOST_NAME=solidtime.test NETWORK_NAME=reverse-proxy-docker-traefik_routing +FORWARD_DB_PORT=5432 +FORWARD_WEB_PORT=8083 diff --git a/.gitignore b/.gitignore index ffdee140..7500b583 100644 --- a/.gitignore +++ b/.gitignore @@ -26,4 +26,7 @@ yarn-error.log /blob-report/ /playwright/.cache/ /coverage -/extensions/* +/extensions +!/extensions/.gitkeep +/auth.json +/modules_statuses.json diff --git a/app/Http/Controllers/Web/HomeController.php b/app/Http/Controllers/Web/HomeController.php new file mode 100644 index 00000000..e0c42976 --- /dev/null +++ b/app/Http/Controllers/Web/HomeController.php @@ -0,0 +1,20 @@ +route('dashboard'); + } else { + return redirect('login'); + } + } +} diff --git a/composer.json b/composer.json index 05df6f08..0473e838 100644 --- a/composer.json +++ b/composer.json @@ -17,10 +17,12 @@ "laravel/jetstream": "^5.0", "laravel/passport": "^12.0", "laravel/tinker": "^2.8", + "nwidart/laravel-modules": "^11.0.3", "pxlrbt/filament-environment-indicator": "^2.0", "spatie/temporary-directory": "^2.2", "tightenco/ziggy": "^2.1.0", - "tpetry/laravel-postgresql-enhanced": "^0.37.0" + "tpetry/laravel-postgresql-enhanced": "^0.37.0", + "wikimedia/composer-merge-plugin": "^2.1.0" }, "require-dev": { "brianium/paratest": "^7.3", @@ -39,6 +41,7 @@ "autoload": { "psr-4": { "App\\": "app/", + "Extensions\\": "extensions/", "Database\\Factories\\": "database/factories/", "Database\\Seeders\\": "database/seeders/" } @@ -90,6 +93,11 @@ "dont-discover": [ "laravel/telescope" ] + }, + "merge-plugin": { + "include": [ + "extensions/*/composer.json" + ] } }, "repositories": [ @@ -104,7 +112,8 @@ "sort-packages": true, "allow-plugins": { "pestphp/pest-plugin": true, - "php-http/discovery": true + "php-http/discovery": true, + "wikimedia/composer-merge-plugin": true } }, "minimum-stability": "stable", diff --git a/composer.lock b/composer.lock index b764576c..d140fd3f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5fba69cdc5c5883dc10412fb2f747740", + "content-hash": "fe04c0899d02909f25d2eb539008b0ff", "packages": [ { "name": "anourvalar/eloquent-serialize", @@ -1431,16 +1431,16 @@ }, { "name": "filament/actions", - "version": "v3.2.60", + "version": "v3.2.61", "source": { "type": "git", "url": "https://github.com/filamentphp/actions.git", - "reference": "8523fabf8d48301d80023d3955bc2d21e52b1e2f" + "reference": "95c8842023399cdf2508a86c2af3db579b125cc7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/actions/zipball/8523fabf8d48301d80023d3955bc2d21e52b1e2f", - "reference": "8523fabf8d48301d80023d3955bc2d21e52b1e2f", + "url": "https://api.github.com/repos/filamentphp/actions/zipball/95c8842023399cdf2508a86c2af3db579b125cc7", + "reference": "95c8842023399cdf2508a86c2af3db579b125cc7", "shasum": "" }, "require": { @@ -1480,20 +1480,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2024-03-21T22:43:16+00:00" + "time": "2024-03-27T12:36:15+00:00" }, { "name": "filament/filament", - "version": "v3.2.60", + "version": "v3.2.61", "source": { "type": "git", "url": "https://github.com/filamentphp/panels.git", - "reference": "08673dba066dcb54cf9019596ffea3d79997496c" + "reference": "6aa99147005785e0528e9eca77ee029c7c57d620" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/panels/zipball/08673dba066dcb54cf9019596ffea3d79997496c", - "reference": "08673dba066dcb54cf9019596ffea3d79997496c", + "url": "https://api.github.com/repos/filamentphp/panels/zipball/6aa99147005785e0528e9eca77ee029c7c57d620", + "reference": "6aa99147005785e0528e9eca77ee029c7c57d620", "shasum": "" }, "require": { @@ -1545,20 +1545,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2024-03-23T20:58:51+00:00" + "time": "2024-03-27T12:36:01+00:00" }, { "name": "filament/forms", - "version": "v3.2.60", + "version": "v3.2.61", "source": { "type": "git", "url": "https://github.com/filamentphp/forms.git", - "reference": "c864c8ac34e1372964d2d4e9595d10ddaabf88c8" + "reference": "1237e83354fd28a1a4cf5d6585f57adc56954e6c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/forms/zipball/c864c8ac34e1372964d2d4e9595d10ddaabf88c8", - "reference": "c864c8ac34e1372964d2d4e9595d10ddaabf88c8", + "url": "https://api.github.com/repos/filamentphp/forms/zipball/1237e83354fd28a1a4cf5d6585f57adc56954e6c", + "reference": "1237e83354fd28a1a4cf5d6585f57adc56954e6c", "shasum": "" }, "require": { @@ -1601,20 +1601,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2024-03-23T23:27:26+00:00" + "time": "2024-03-27T12:35:57+00:00" }, { "name": "filament/infolists", - "version": "v3.2.60", + "version": "v3.2.61", "source": { "type": "git", "url": "https://github.com/filamentphp/infolists.git", - "reference": "64d1ed73e05eebb688e343348e126a038169c7d0" + "reference": "aa2f266ce113b13cf24e8752970bed9d2fb62b4f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/infolists/zipball/64d1ed73e05eebb688e343348e126a038169c7d0", - "reference": "64d1ed73e05eebb688e343348e126a038169c7d0", + "url": "https://api.github.com/repos/filamentphp/infolists/zipball/aa2f266ce113b13cf24e8752970bed9d2fb62b4f", + "reference": "aa2f266ce113b13cf24e8752970bed9d2fb62b4f", "shasum": "" }, "require": { @@ -1652,20 +1652,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2024-03-23T23:27:28+00:00" + "time": "2024-03-27T12:36:20+00:00" }, { "name": "filament/notifications", - "version": "v3.2.60", + "version": "v3.2.61", "source": { "type": "git", "url": "https://github.com/filamentphp/notifications.git", - "reference": "f9a790ee2d5103ea87c88e6d545ea6ceb770cbe5" + "reference": "069a37c9f260918741fd80167859d7578ea18887" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/notifications/zipball/f9a790ee2d5103ea87c88e6d545ea6ceb770cbe5", - "reference": "f9a790ee2d5103ea87c88e6d545ea6ceb770cbe5", + "url": "https://api.github.com/repos/filamentphp/notifications/zipball/069a37c9f260918741fd80167859d7578ea18887", + "reference": "069a37c9f260918741fd80167859d7578ea18887", "shasum": "" }, "require": { @@ -1704,20 +1704,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2024-03-19T00:28:12+00:00" + "time": "2024-03-27T12:36:01+00:00" }, { "name": "filament/support", - "version": "v3.2.60", + "version": "v3.2.61", "source": { "type": "git", "url": "https://github.com/filamentphp/support.git", - "reference": "05c0c56bdb66226dc8d239ac91bc973a0dd33edb" + "reference": "6f7f6fe72f8c206bd28297fbf41f863358c95c07" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/support/zipball/05c0c56bdb66226dc8d239ac91bc973a0dd33edb", - "reference": "05c0c56bdb66226dc8d239ac91bc973a0dd33edb", + "url": "https://api.github.com/repos/filamentphp/support/zipball/6f7f6fe72f8c206bd28297fbf41f863358c95c07", + "reference": "6f7f6fe72f8c206bd28297fbf41f863358c95c07", "shasum": "" }, "require": { @@ -1761,20 +1761,20 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2024-03-23T20:59:06+00:00" + "time": "2024-03-27T12:36:25+00:00" }, { "name": "filament/tables", - "version": "v3.2.60", + "version": "v3.2.61", "source": { "type": "git", "url": "https://github.com/filamentphp/tables.git", - "reference": "b58dbfd4b3f4da6708e67a4ca0512bc914faa991" + "reference": "38e01c5d5e841d36365d2acf581ed60095b0f768" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filamentphp/tables/zipball/b58dbfd4b3f4da6708e67a4ca0512bc914faa991", - "reference": "b58dbfd4b3f4da6708e67a4ca0512bc914faa991", + "url": "https://api.github.com/repos/filamentphp/tables/zipball/38e01c5d5e841d36365d2acf581ed60095b0f768", + "reference": "38e01c5d5e841d36365d2acf581ed60095b0f768", "shasum": "" }, "require": { @@ -1814,11 +1814,11 @@ "issues": "https://github.com/filamentphp/filament/issues", "source": "https://github.com/filamentphp/filament" }, - "time": "2024-03-23T20:59:09+00:00" + "time": "2024-03-27T12:36:41+00:00" }, { "name": "filament/widgets", - "version": "v3.2.60", + "version": "v3.2.61", "source": { "type": "git", "url": "https://github.com/filamentphp/widgets.git", @@ -2668,6 +2668,88 @@ }, "time": "2024-02-28T15:07:15+00:00" }, + { + "name": "laravel/cashier-paddle", + "version": "v2.4.0", + "source": { + "type": "git", + "url": "https://github.com/laravel/cashier-paddle.git", + "reference": "435ae901784f414471184c5b28efe39a09c3d758" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/cashier-paddle/zipball/435ae901784f414471184c5b28efe39a09c3d758", + "reference": "435ae901784f414471184c5b28efe39a09c3d758", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-openssl": "*", + "guzzlehttp/guzzle": "^7.4.5", + "illuminate/contracts": "^10.0|^11.0", + "illuminate/database": "^10.0|^11.0", + "illuminate/http": "^10.0|^11.0", + "illuminate/routing": "^10.0|^11.0", + "illuminate/support": "^10.0|^11.0", + "illuminate/view": "^10.0|^11.0", + "moneyphp/money": "^3.2|^4.0", + "nesbot/carbon": "^2.67|^3.0", + "php": "^8.1", + "spatie/url": "^1.3.5|^2.0", + "symfony/http-kernel": "^6.2|^7.0", + "symfony/polyfill-intl-icu": "^1.22.1" + }, + "require-dev": { + "mockery/mockery": "^1.5.1", + "orchestra/testbench": "^8.14|^9.0", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^10.4" + }, + "suggest": { + "ext-intl": "Allows for more locales besides the default \"en\" when formatting money values." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + }, + "laravel": { + "providers": [ + "Laravel\\Paddle\\CashierServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Paddle\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + }, + { + "name": "Dries Vints", + "email": "dries@laravel.com" + } + ], + "description": "Cashier Paddle provides an expressive, fluent interface to Paddle's subscription billing services.", + "keywords": [ + "billing", + "laravel", + "paddle" + ], + "support": { + "issues": "https://github.com/laravel/cashier-paddle/issues", + "source": "https://github.com/laravel/cashier-paddle" + }, + "time": "2024-02-27T17:02:47+00:00" + }, { "name": "laravel/fortify", "version": "v1.21.1", @@ -3198,6 +3280,78 @@ }, "time": "2023-11-08T14:08:06+00:00" }, + { + "name": "laravel/spark-paddle", + "version": "v5.1.5", + "source": { + "type": "git", + "url": "git@github.com:laravel/spark-paddle.git", + "reference": "2c295f24ddf5cc49fb914a8bd6a6d9701a0fc528" + }, + "dist": { + "type": "zip", + "url": "https://spark.laravel.com/dist/laravel/spark-paddle/laravel-spark-paddle-2c295f24ddf5cc49fb914a8bd6a6d9701a0fc528-zip-43b330.zip", + "reference": "2c295f24ddf5cc49fb914a8bd6a6d9701a0fc528", + "shasum": "6c06b703aa701801f363ef5f7d4645526353cbb5" + }, + "require": { + "ext-bcmath": "*", + "ext-json": "*", + "illuminate/contracts": "^10.0|^11.0", + "inertiajs/inertia-laravel": "^0.6.4|^1.0", + "laravel/cashier-paddle": "^2.0.5", + "php": "^8.1" + }, + "require-dev": { + "mockery/mockery": "^1.0", + "orchestra/testbench": "^8.14|^9.0", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^10.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + }, + "laravel": { + "providers": [ + "Spark\\SparkServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Spark\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "Spark\\Tests\\": "tests/" + } + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Laravel Spark provides scaffolding for Laravel SaaS applications.", + "keywords": [ + "billing", + "laravel", + "paddle", + "saas", + "scaffolding" + ], + "support": { + "source": "https://github.com/laravel/spark-paddle/tree/v5.1.5", + "issues": "https://github.com/laravel/spark-paddle/issues" + }, + "time": "2024-03-19T16:24:28+00:00" + }, { "name": "laravel/tinker", "version": "v2.9.0", @@ -4405,6 +4559,94 @@ ], "time": "2024-03-01T22:28:42+00:00" }, + { + "name": "moneyphp/money", + "version": "v4.5.0", + "source": { + "type": "git", + "url": "https://github.com/moneyphp/money.git", + "reference": "a1daa7daf159b4044e3d0c34c41fe2be5860e850" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/moneyphp/money/zipball/a1daa7daf159b4044e3d0c34c41fe2be5860e850", + "reference": "a1daa7daf159b4044e3d0c34c41fe2be5860e850", + "shasum": "" + }, + "require": { + "ext-bcmath": "*", + "ext-filter": "*", + "ext-json": "*", + "php": "~8.1.0 || ~8.2.0 || ~8.3.0" + }, + "require-dev": { + "cache/taggable-cache": "^1.1.0", + "doctrine/coding-standard": "^12.0", + "doctrine/instantiator": "^1.5.0 || ^2.0", + "ext-gmp": "*", + "ext-intl": "*", + "florianv/exchanger": "^2.8.1", + "florianv/swap": "^4.3.0", + "moneyphp/crypto-currencies": "^1.1.0", + "moneyphp/iso-currencies": "^3.4", + "php-http/message": "^1.16.0", + "php-http/mock-client": "^1.6.0", + "phpbench/phpbench": "^1.2.5", + "phpunit/phpunit": "^10.5.9", + "psalm/plugin-phpunit": "^0.18.4", + "psr/cache": "^1.0.1 || ^2.0 || ^3.0", + "vimeo/psalm": "~5.20.0" + }, + "suggest": { + "ext-gmp": "Calculate without integer limits", + "ext-intl": "Format Money objects with intl", + "florianv/exchanger": "Exchange rates library for PHP", + "florianv/swap": "Exchange rates library for PHP", + "psr/cache-implementation": "Used for Currency caching" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Money\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mathias Verraes", + "email": "mathias@verraes.net", + "homepage": "http://verraes.net" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + }, + { + "name": "Frederik Bosch", + "email": "f.bosch@genkgo.nl" + } + ], + "description": "PHP implementation of Fowler's Money pattern", + "homepage": "http://moneyphp.org", + "keywords": [ + "Value Object", + "money", + "vo" + ], + "support": { + "issues": "https://github.com/moneyphp/money/issues", + "source": "https://github.com/moneyphp/money/tree/v4.5.0" + }, + "time": "2024-02-15T19:47:21+00:00" + }, { "name": "monolog/monolog", "version": "3.5.0", @@ -4508,16 +4750,16 @@ }, { "name": "nesbot/carbon", - "version": "3.1.1", + "version": "3.2.1", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "34ccf6f6b49c915421c7886c88c0cb77f3ebbfd2" + "reference": "b4272c2e78d30f9085b079aedb692b2da879b313" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/34ccf6f6b49c915421c7886c88c0cb77f3ebbfd2", - "reference": "34ccf6f6b49c915421c7886c88c0cb77f3ebbfd2", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/b4272c2e78d30f9085b079aedb692b2da879b313", + "reference": "b4272c2e78d30f9085b079aedb692b2da879b313", "shasum": "" }, "require": { @@ -4535,14 +4777,14 @@ "require-dev": { "doctrine/dbal": "^3.6.3 || ^4.0", "doctrine/orm": "^2.15.2 || ^3.0", - "friendsofphp/php-cs-fixer": "^3.18.0", - "kylekatarnls/multi-tester": "^2.2.0", - "ondrejmirtes/better-reflection": "^6.11.0.0", - "phpmd/phpmd": "^2.13.0", - "phpstan/extension-installer": "^1.3.0", - "phpstan/phpstan": "^1.10.20", - "phpunit/phpunit": "^10.2.2", - "squizlabs/php_codesniffer": "^3.7.2" + "friendsofphp/php-cs-fixer": "^3.52.1", + "kylekatarnls/multi-tester": "^2.5.3", + "ondrejmirtes/better-reflection": "^6.25.0.4", + "phpmd/phpmd": "^2.15.0", + "phpstan/extension-installer": "^1.3.1", + "phpstan/phpstan": "^1.10.65", + "phpunit/phpunit": "^10.5.15", + "squizlabs/php_codesniffer": "^3.9.0" }, "bin": [ "bin/carbon" @@ -4610,7 +4852,7 @@ "type": "tidelift" } ], - "time": "2024-03-13T12:42:37+00:00" + "time": "2024-03-27T21:37:24+00:00" }, { "name": "nette/schema", @@ -4906,6 +5148,92 @@ ], "time": "2024-03-06T16:17:14+00:00" }, + { + "name": "nwidart/laravel-modules", + "version": "v11.0.3", + "source": { + "type": "git", + "url": "https://github.com/nWidart/laravel-modules.git", + "reference": "24c5ca340cf9d5cb8d71ebc27e8a5ac70e599a87" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nWidart/laravel-modules/zipball/24c5ca340cf9d5cb8d71ebc27e8a5ac70e599a87", + "reference": "24c5ca340cf9d5cb8d71ebc27e8a5ac70e599a87", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": ">=8.2", + "wikimedia/composer-merge-plugin": "^2.1" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^v3.52", + "laravel/framework": "^v11.0", + "mockery/mockery": "^1.6", + "orchestra/testbench": "^v9.0", + "phpstan/phpstan": "^1.4", + "phpunit/phpunit": "^11.0", + "spatie/phpunit-snapshot-assertions": "^5.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Nwidart\\Modules\\LaravelModulesServiceProvider" + ], + "aliases": { + "Module": "Nwidart\\Modules\\Facades\\Module" + } + }, + "branch-alias": { + "dev-master": "11.0-dev" + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Nwidart\\Modules\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Widart", + "email": "n.widart@gmail.com", + "homepage": "https://nicolaswidart.com", + "role": "Developer" + } + ], + "description": "Laravel Module management", + "keywords": [ + "laravel", + "module", + "modules", + "nwidart", + "rad" + ], + "support": { + "issues": "https://github.com/nWidart/laravel-modules/issues", + "source": "https://github.com/nWidart/laravel-modules/tree/v11.0.3" + }, + "funding": [ + { + "url": "https://github.com/dcblogdev", + "type": "github" + }, + { + "url": "https://github.com/nwidart", + "type": "github" + } + ], + "time": "2024-03-24T23:33:15+00:00" + }, { "name": "nyholm/psr7", "version": "1.8.1", @@ -6561,6 +6889,56 @@ ], "time": "2024-03-20T07:29:11+00:00" }, + { + "name": "spatie/macroable", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/macroable.git", + "reference": "ec2c320f932e730607aff8052c44183cf3ecb072" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/macroable/zipball/ec2c320f932e730607aff8052c44183cf3ecb072", + "reference": "ec2c320f932e730607aff8052c44183cf3ecb072", + "shasum": "" + }, + "require": { + "php": "^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.0|^9.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\Macroable\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "A trait to dynamically add methods to a class", + "homepage": "https://github.com/spatie/macroable", + "keywords": [ + "macroable", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/macroable/issues", + "source": "https://github.com/spatie/macroable/tree/2.0.0" + }, + "time": "2021-03-26T22:39:02+00:00" + }, { "name": "spatie/regex", "version": "3.1.1", @@ -6685,6 +7063,68 @@ ], "time": "2023-12-25T11:46:58+00:00" }, + { + "name": "spatie/url", + "version": "2.4.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/url.git", + "reference": "93a51db743cdec22b081c64593e193887c9cd395" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/url/zipball/93a51db743cdec22b081c64593e193887c9cd395", + "reference": "93a51db743cdec22b081c64593e193887c9cd395", + "shasum": "" + }, + "require": { + "php": "^8.0", + "psr/http-message": "^1.0 || ^2.0", + "spatie/macroable": "^1.0 || ^2.0" + }, + "require-dev": { + "pestphp/pest": "^1.21" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\Url\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Sebastian De Deyne", + "email": "sebastian@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "Parse, build and manipulate URL's", + "homepage": "https://github.com/spatie/url", + "keywords": [ + "spatie", + "url" + ], + "support": { + "issues": "https://github.com/spatie/url/issues", + "source": "https://github.com/spatie/url/tree/2.4.0" + }, + "funding": [ + { + "url": "https://spatie.be/open-source/support-us", + "type": "custom" + }, + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2024-03-08T11:35:19+00:00" + }, { "name": "symfony/clock", "version": "v7.0.5", @@ -7857,6 +8297,90 @@ ], "time": "2024-01-29T20:11:03+00:00" }, + { + "name": "symfony/polyfill-intl-icu", + "version": "v1.29.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-icu.git", + "reference": "07094a28851a49107f3ab4f9120ca2975a64b6e1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-icu/zipball/07094a28851a49107f3ab4f9120ca2975a64b6e1", + "reference": "07094a28851a49107f3ab4f9120ca2975a64b6e1", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance and support of other locales than \"en\"" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Icu\\": "" + }, + "classmap": [ + "Resources/stubs" + ], + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's ICU-related data and classes", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "icu", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-icu/tree/v1.29.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-01-29T20:12:16+00:00" + }, { "name": "symfony/polyfill-intl-idn", "version": "v1.29.0", @@ -9536,6 +10060,62 @@ "source": "https://github.com/webmozarts/assert/tree/1.11.0" }, "time": "2022-06-03T18:03:27+00:00" + }, + { + "name": "wikimedia/composer-merge-plugin", + "version": "v2.1.0", + "source": { + "type": "git", + "url": "https://github.com/wikimedia/composer-merge-plugin.git", + "reference": "a03d426c8e9fb2c9c569d9deeb31a083292788bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wikimedia/composer-merge-plugin/zipball/a03d426c8e9fb2c9c569d9deeb31a083292788bc", + "reference": "a03d426c8e9fb2c9c569d9deeb31a083292788bc", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.1||^2.0", + "php": ">=7.2.0" + }, + "require-dev": { + "composer/composer": "^1.1||^2.0", + "ext-json": "*", + "mediawiki/mediawiki-phan-config": "0.11.1", + "php-parallel-lint/php-parallel-lint": "~1.3.1", + "phpspec/prophecy": "~1.15.0", + "phpunit/phpunit": "^8.5||^9.0", + "squizlabs/php_codesniffer": "~3.7.1" + }, + "type": "composer-plugin", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + }, + "class": "Wikimedia\\Composer\\Merge\\V2\\MergePlugin" + }, + "autoload": { + "psr-4": { + "Wikimedia\\Composer\\Merge\\V2\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bryan Davis", + "email": "bd808@wikimedia.org" + } + ], + "description": "Composer plugin to merge multiple composer.json files", + "support": { + "issues": "https://github.com/wikimedia/composer-merge-plugin/issues", + "source": "https://github.com/wikimedia/composer-merge-plugin/tree/v2.1.0" + }, + "time": "2023-04-15T19:07:00+00:00" } ], "packages-dev": [ diff --git a/config/modules.php b/config/modules.php new file mode 100644 index 00000000..b00bbbee --- /dev/null +++ b/config/modules.php @@ -0,0 +1,234 @@ + 'Extensions', + + /* + |-------------------------------------------------------------------------- + | Module Stubs + |-------------------------------------------------------------------------- + | + | Default module stubs. + | + */ + + 'stubs' => [ + 'enabled' => false, + 'path' => base_path('vendor/nwidart/laravel-modules/src/Commands/stubs'), + 'files' => [ + 'routes/web' => 'routes/web.php', + 'routes/api' => 'routes/api.php', + 'views/index' => 'resources/views/index.blade.php', + 'views/master' => 'resources/views/layouts/master.blade.php', + 'scaffold/config' => 'config/config.php', + 'composer' => 'composer.json', + 'assets/js/app' => 'resources/assets/js/app.js', + 'assets/sass/app' => 'resources/assets/sass/app.scss', + 'vite' => 'vite.config.js', + 'package' => 'package.json', + ], + 'replacements' => [ + 'routes/web' => ['LOWER_NAME', 'STUDLY_NAME', 'MODULE_NAMESPACE', 'CONTROLLER_NAMESPACE'], + 'routes/api' => ['LOWER_NAME', 'STUDLY_NAME'], + 'vite' => ['LOWER_NAME'], + 'json' => ['LOWER_NAME', 'STUDLY_NAME', 'MODULE_NAMESPACE', 'PROVIDER_NAMESPACE'], + 'views/index' => ['LOWER_NAME'], + 'views/master' => ['LOWER_NAME', 'STUDLY_NAME'], + 'scaffold/config' => ['STUDLY_NAME'], + 'composer' => [ + 'LOWER_NAME', + 'STUDLY_NAME', + 'VENDOR', + 'AUTHOR_NAME', + 'AUTHOR_EMAIL', + 'MODULE_NAMESPACE', + 'PROVIDER_NAMESPACE', + ], + ], + 'gitkeep' => true, + ], + 'paths' => [ + /* + |-------------------------------------------------------------------------- + | Modules path + |-------------------------------------------------------------------------- + | + | This path is used to save the generated module. + | This path will also be added automatically to the list of scanned folders. + | + */ + + 'modules' => base_path('extensions'), + /* + |-------------------------------------------------------------------------- + | Modules assets path + |-------------------------------------------------------------------------- + | + | Here you may update the modules' assets path. + | + */ + + 'assets' => public_path('extensions'), + /* + |-------------------------------------------------------------------------- + | The migrations' path + |-------------------------------------------------------------------------- + | + | Where you run the 'module:publish-migration' command, where do you publish the + | the migration files? + | + */ + + 'migration' => base_path('database/migrations'), + /* + |-------------------------------------------------------------------------- + | Generator path + |-------------------------------------------------------------------------- + | Customise the paths where the folders will be generated. + | Setting the generate key to false will not generate that folder + */ + 'generator' => [ + 'config' => ['path' => 'config', 'generate' => true], + 'command' => ['path' => 'App/Console', 'generate' => false], + 'channels' => ['path' => 'App/Broadcasting', 'generate' => false], + 'migration' => ['path' => 'Database/migrations', 'generate' => false], + 'seeder' => ['path' => 'Database/Seeders', 'generate' => true], + 'factory' => ['path' => 'Database/Factories', 'generate' => false], + 'model' => ['path' => 'App/Models', 'generate' => false], + 'observer' => ['path' => 'App/Observers', 'generate' => false], + 'routes' => ['path' => 'routes', 'generate' => true], + 'controller' => ['path' => 'App/Http/Controllers', 'generate' => true], + 'filter' => ['path' => 'App/Http/Middleware', 'generate' => false], + 'request' => ['path' => 'App/Http/Requests', 'generate' => false], + 'provider' => ['path' => 'App/Providers', 'generate' => true], + 'assets' => ['path' => 'resources/assets', 'generate' => false], + 'lang' => ['path' => 'lang', 'generate' => false], + 'views' => ['path' => 'resources/views', 'generate' => true], + 'test' => ['path' => 'tests/Unit', 'generate' => false], + 'test-feature' => ['path' => 'tests/Feature', 'generate' => false], + 'repository' => ['path' => 'App/Repositories', 'generate' => false], + 'event' => ['path' => 'App/Events', 'generate' => false], + 'listener' => ['path' => 'App/Listeners', 'generate' => false], + 'policies' => ['path' => 'App/Policies', 'generate' => false], + 'rules' => ['path' => 'App/Rules', 'generate' => false], + 'jobs' => ['path' => 'App/Jobs', 'generate' => false], + 'emails' => ['path' => 'App/Emails', 'generate' => false], + 'notifications' => ['path' => 'App/Notifications', 'generate' => false], + 'resource' => ['path' => 'App/resources', 'generate' => false], + 'component-view' => ['path' => 'resources/views/components', 'generate' => false], + 'component-class' => ['path' => 'App/View/Components', 'generate' => false], + ], + ], + + /* + |-------------------------------------------------------------------------- + | Package commands + |-------------------------------------------------------------------------- + | + | Here you can define which commands will be visible and used in your + | application. You can add your own commands to merge section. + | + */ + 'commands' => ConsoleServiceProvider::defaultCommands() + ->merge([ + // New commands go here + ])->toArray(), + + /* + |-------------------------------------------------------------------------- + | Scan Path + |-------------------------------------------------------------------------- + | + | Here you define which folder will be scanned. By default will scan vendor + | directory. This is useful if you host the package in packagist website. + | + */ + + 'scan' => [ + 'enabled' => false, + 'paths' => [ + base_path('vendor/*/*'), + ], + ], + /* + |-------------------------------------------------------------------------- + | Composer File Template + |-------------------------------------------------------------------------- + | + | Here is the config for the composer.json file, generated by this package + | + */ + + 'composer' => [ + 'vendor' => 'nwidart', + 'author' => [ + 'name' => 'Nicolas Widart', + 'email' => 'n.widart@gmail.com', + ], + 'composer-output' => false, + ], + + /* + |-------------------------------------------------------------------------- + | Caching + |-------------------------------------------------------------------------- + | + | Here is the config for setting up the caching feature. + | + */ + 'cache' => [ + 'enabled' => false, + 'driver' => 'file', + 'key' => 'laravel-modules', + 'lifetime' => 60, + ], + /* + |-------------------------------------------------------------------------- + | Choose what laravel-modules will register as custom namespaces. + | Setting one to false will require you to register that part + | in your own Service Provider class. + |-------------------------------------------------------------------------- + */ + 'register' => [ + 'translations' => true, + /** + * load files on boot or register method + */ + 'files' => 'register', + ], + + /* + |-------------------------------------------------------------------------- + | Activators + |-------------------------------------------------------------------------- + | + | You can define new types of activators here, file, database, etc. The only + | required parameter is 'class'. + | The file activator will store the activation status in storage/installed_modules + */ + 'activators' => [ + 'file' => [ + 'class' => FileActivator::class, + 'statuses-file' => base_path('modules_statuses.json'), + 'cache-key' => 'activator.installed', + 'cache-lifetime' => 604800, + ], + ], + + 'activator' => 'file', +]; diff --git a/docker-compose.yml b/docker-compose.yml index c3c40774..73e7452d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -5,6 +5,8 @@ services: dockerfile: Dockerfile args: WWWGROUP: '${WWWGROUP}' + ports: + - '${FORWARD_WEB_PORT:-8083}:80' image: sail-8.3/app labels: - "traefik.enable=true" diff --git a/routes/web.php b/routes/web.php index 50de4e47..bc637009 100644 --- a/routes/web.php +++ b/routes/web.php @@ -3,9 +3,9 @@ declare(strict_types=1); use App\Http\Controllers\Web\DashboardController; +use App\Http\Controllers\Web\HomeController; use Illuminate\Foundation\Application; use Illuminate\Support\Facades\Route; -use Inertia\Inertia; /* |-------------------------------------------------------------------------- @@ -18,14 +18,7 @@ | */ -Route::get('/', function () { - return Inertia::render('Welcome', [ - 'canLogin' => Route::has('login'), - 'canRegister' => Route::has('register'), - 'laravelVersion' => Application::VERSION, - 'phpVersion' => PHP_VERSION, - ]); -}); +Route::get('/', [HomeController::class, 'index']); Route::middleware([ 'auth:web', diff --git a/tests/Unit/Endpoint/Web/HomeEndpointTest.php b/tests/Unit/Endpoint/Web/HomeEndpointTest.php new file mode 100644 index 00000000..c12de40d --- /dev/null +++ b/tests/Unit/Endpoint/Web/HomeEndpointTest.php @@ -0,0 +1,34 @@ +withPersonalOrganization()->create(); + $this->actingAs($user); + + // Act + $response = $this->get('/'); + + // Assert + $response->assertRedirect('/dashboard'); + } + + public function test_index_redirects_to_login_if_user_is_not_logged_in(): void + { + // Arrange + + // Act + $response = $this->get('/'); + + // Assert + $response->assertRedirect('/login'); + } +} diff --git a/vite-module-loader.js b/vite-module-loader.js new file mode 100644 index 00000000..ab41f226 --- /dev/null +++ b/vite-module-loader.js @@ -0,0 +1,45 @@ +import fs from 'fs/promises'; +import path from 'path'; + +async function collectModuleAssetsPaths(paths, modulesPath) { + modulesPath = path.join(__dirname, modulesPath); + + const moduleStatusesPath = path.join(__dirname, 'modules_statuses.json'); + + try { + // Read module_statuses.json + const moduleStatusesContent = await fs.readFile(moduleStatusesPath, 'utf-8'); + const moduleStatuses = JSON.parse(moduleStatusesContent); + + // Read module directories + const moduleDirectories = await fs.readdir(modulesPath); + + for (const moduleDir of moduleDirectories) { + if (moduleDir === '.DS_Store') { + // Skip .DS_Store directory + continue; + } + + // Check if the module is enabled (status is true) + if (moduleStatuses[moduleDir] === true) { + const viteConfigPath = path.join(modulesPath, moduleDir, 'vite.config.js'); + const stat = await fs.stat(viteConfigPath); + + if (stat.isFile()) { + // Import the module-specific Vite configuration + const moduleConfig = await import(viteConfigPath); + + if (moduleConfig.paths && Array.isArray(moduleConfig.paths)) { + paths.push(...moduleConfig.paths); + } + } + } + } + } catch (error) { + console.error(`Error reading module statuses or module configurations: ${error}`); + } + + return paths; +} + +export default collectModuleAssetsPaths;