├── .devcontainer └── devcontainer.json ├── .dockerignore ├── .editorconfig ├── .env.example ├── .fly ├── entrypoint.sh └── scripts │ └── caches.sh ├── .gitattributes ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── feature_request.md │ ├── initialization-error.md │ └── other.md ├── dependabot.yml └── workflows │ ├── build_docker_images.yml │ └── main.yml ├── .gitignore ├── .styleci.yml ├── Dockerfile ├── LICENSE.md ├── README.md ├── app ├── AppServiceProvider.php ├── ExceptionHandler.php ├── HttpKernel.php ├── SentryTracingSampler.php ├── TrustProxies.php └── helpers.php ├── artisan ├── bootstrap ├── app.php └── cache │ └── .gitignore ├── composer.json ├── composer.lock ├── config ├── app.php ├── cache.php ├── database.php ├── filesystems.php ├── google-fonts.php ├── hashing.php ├── logging.php ├── queue.php ├── sentry.php ├── session.php └── view.php ├── database └── migrations │ └── 2022_01_25_225659_create_statistics_table.php ├── docker-compose.yml ├── docker ├── 8.0 │ ├── Dockerfile │ ├── php.ini │ ├── start-container │ └── supervisord.conf ├── 8.1 │ ├── Dockerfile │ ├── php.ini │ ├── start-container │ └── supervisord.conf └── 8.2 │ ├── Dockerfile │ ├── php.ini │ ├── start-container │ └── supervisord.conf ├── domains ├── ArchiveManipulation │ ├── ArchiveManipulator.php │ ├── ArchiveManipulatorResolver.php │ ├── MissingArchiveManipulatorInterfaceException.php │ ├── README.md │ └── RegistersArchiveManipulators.php ├── Composer │ ├── ComposerDependency.php │ ├── ComposerJsonFile.php │ ├── ComposerServiceProvider.php │ ├── InlineComposerDependency.php │ ├── LogIO.php │ ├── NoInstallationCandidateFoundException.php │ ├── PackageName.php │ ├── PackageVersionToInstallResolver.php │ ├── PackageWithResolvedVersion.php │ ├── ProjectTemplateCustomization │ │ ├── ComposerJsonArchiveManipulator.php │ │ └── ComposerJsonGenerator.php │ └── VersionSelectorFactory.php ├── ConfigAdjustment │ ├── BroadcastingAdjuster.php │ ├── CacheAdjuster.php │ ├── Concerns │ │ └── MakesArchiveAdjustments.php │ ├── ConfigAdjustmentArchiveManipulator.php │ ├── ConfigAdjustmentServiceProvider.php │ ├── DatabaseAdjuster.php │ ├── FlysystemAdjuster.php │ └── SearchAdjuster.php ├── CreateProjectForm │ ├── Components │ │ ├── Logo.php │ │ └── StarterKit │ │ │ ├── Breeze.php │ │ │ ├── Jetstream.php │ │ │ ├── Laravel.php │ │ │ ├── Option.php │ │ │ └── Selector.php │ ├── CreateProjectForm.php │ ├── CreateProjectFormServiceProvider.php │ ├── Http │ │ ├── Controllers │ │ │ ├── CreateProjectController.php │ │ │ ├── PermalinkController.php │ │ │ └── ShowFormController.php │ │ ├── Request │ │ │ ├── CreateProjectRequest.php │ │ │ └── CreateProjectRequest │ │ │ │ ├── BuildsCreateProjectForm.php │ │ │ │ ├── CreateProjectRequestParameter.php │ │ │ │ ├── CreateProjectRequestParameterLabel.php │ │ │ │ └── NormalizesInputs.php │ │ └── Routes.php │ ├── Sections │ │ ├── Authentication.php │ │ ├── Broadcasting.php │ │ ├── Broadcasting │ │ │ └── BroadcastingChannelOption.php │ │ ├── Cache.php │ │ ├── Cache │ │ │ ├── CacheDriver.php │ │ │ ├── CacheOption.php │ │ │ ├── DynamoDBCacheDBDriver.php │ │ │ ├── MemcacheDCacheDriver.php │ │ │ └── RedisCacheDriver.php │ │ ├── Cashier │ │ │ ├── CashierDriver.php │ │ │ ├── CashierDriverOption.php │ │ │ ├── CashierMollieDriver.php │ │ │ ├── CashierPaddleDriver.php │ │ │ └── CashierStripeDriver.php │ │ ├── Database.php │ │ ├── Database │ │ │ └── DatabaseOption.php │ │ ├── DevelopmentTools.php │ │ ├── Mail.php │ │ ├── Mail │ │ │ └── MailDriverOption.php │ │ ├── Metadata.php │ │ ├── Metadata │ │ │ └── PhpVersion.php │ │ ├── Notifications.php │ │ ├── Notifications │ │ │ └── NotificationChannelOptions.php │ │ ├── Payment.php │ │ ├── Queue.php │ │ ├── Queue │ │ │ ├── BeanstalkdQueueDriver.php │ │ │ ├── QueueDriver.php │ │ │ ├── QueueDriverOption.php │ │ │ ├── RedisQueueDriver.php │ │ │ └── SqsQueueDriver.php │ │ ├── Scout │ │ │ └── ScoutDriver.php │ │ ├── Search.php │ │ ├── Storage.php │ │ └── Testing.php │ ├── Support │ │ └── Str.php │ ├── Validation │ │ └── Rules │ │ │ ├── ValidBreezeFrontendOption.php │ │ │ ├── ValidCacheOption.php │ │ │ ├── ValidCashierDriverOption.php │ │ │ ├── ValidDatabaseOption.php │ │ │ ├── ValidJetstreamFrontendOption.php │ │ │ ├── ValidPhpVersionOption.php │ │ │ ├── ValidQueueDriverOption.php │ │ │ └── ValidStarterKitOption.php │ └── resources │ │ └── views │ │ └── starter-kit │ │ ├── breeze.blade.php │ │ ├── jetstream.blade.php │ │ ├── laravel.blade.php │ │ ├── starter-option.blade.php │ │ └── starter-selector.blade.php ├── DockerImages │ ├── Console │ │ └── Commands │ │ │ └── UpdateSailImages.php │ └── DockerImagesServiceProvider.php ├── InitializationScript │ ├── InitializationScriptArchiveManipulator.php │ ├── InitializationScriptGenerator.php │ ├── InitializationScriptServiceProvider.php │ ├── README.md │ ├── View │ │ └── Components │ │ │ ├── Initialize │ │ │ ├── Cleanup.php │ │ │ ├── DoneBanner.php │ │ │ ├── EnsureDockerIsRunning.php │ │ │ ├── ErrorHandler.php │ │ │ ├── TaskGroup.php │ │ │ └── WelcomeBanner.php │ │ │ └── Shell │ │ │ ├── Banner.php │ │ │ ├── BannerLine.php │ │ │ ├── Bold.php │ │ │ └── ConfirmExecution.php │ └── resources │ │ └── templates │ │ └── initialize.blade.php ├── Laravel │ ├── ComposerPackages │ │ ├── FirstPartyDependencyRepository.php │ │ ├── FirstPartyPackage.php │ │ ├── Packages │ │ │ ├── Breeze.php │ │ │ ├── CashierMollie.php │ │ │ ├── CashierPaddle.php │ │ │ ├── CashierStripe.php │ │ │ ├── Dusk.php │ │ │ ├── Envoy.php │ │ │ ├── Fortify.php │ │ │ ├── Horizon.php │ │ │ ├── Jetstream.php │ │ │ ├── Pail.php │ │ │ ├── Passport.php │ │ │ ├── Pennant.php │ │ │ ├── Sanctum.php │ │ │ ├── Scout.php │ │ │ ├── Socialite.php │ │ │ └── Telescope.php │ │ └── ProvidesInstallationInstructions.php │ ├── NpmPackages │ │ └── LaravelEcho.php │ ├── RelatedPackages │ │ ├── Broadcasting │ │ │ ├── Ably.php │ │ │ ├── LaravelWebsockets.php │ │ │ ├── Pusher.php │ │ │ ├── PusherJs.php │ │ │ └── Soketi.php │ │ ├── Database │ │ │ └── DoctrineDbal.php │ │ ├── Infrastructure │ │ │ ├── AwsSdk.php │ │ │ └── Flysystem │ │ │ │ ├── FtpDriver.php │ │ │ │ ├── ReadonlyDriver.php │ │ │ │ ├── S3Driver.php │ │ │ │ ├── ScopedDriver.php │ │ │ │ └── SftpDriver.php │ │ ├── Mail │ │ │ ├── MailgunMailer.php │ │ │ └── PostmarkMailer.php │ │ ├── Search │ │ │ └── Algolia.php │ │ └── Testing │ │ │ └── Pest.php │ ├── Sail │ │ ├── DatabaseOption.php │ │ ├── Mailhog.php │ │ ├── MariaDatabase.php │ │ ├── MeiliSearch.php │ │ ├── Memcached.php │ │ ├── MinIO.php │ │ ├── MySQLDatabase.php │ │ ├── PostgresDatabase.php │ │ ├── Redis.php │ │ ├── SailConfigurationOption.php │ │ ├── SailServiceRepository.php │ │ ├── Selenium.php │ │ └── Soketi.php │ └── StarterKit │ │ ├── Breeze.php │ │ ├── BreezeFrontend.php │ │ ├── Jetstream.php │ │ ├── JetstreamFrontend.php │ │ ├── Laravel.php │ │ └── StarterKit.php ├── NodeJs │ └── NpmDependency.php ├── Packagist │ ├── Models │ │ ├── Package.php │ │ └── PackageDist.php │ └── PackagistApiClient.php ├── PostDownload │ ├── ClosurePostInstallTaskGroup.php │ ├── PostDownloadTask.php │ ├── PostDownloadTaskGroup.php │ ├── PostDownloadTaskGroupCreator.php │ ├── PostDownloadTaskRenderer.php │ ├── PostInitializationLink.php │ ├── PostInitializationLinkResolver.php │ ├── Tasks │ │ ├── AdjustPermissions.php │ │ ├── InstallDevcontainer.php │ │ ├── MigrateDatabase.php │ │ ├── SetupFrontend.php │ │ ├── SetupPackages.php │ │ ├── SetupSail.php │ │ ├── StartSail.php │ │ └── WaitForDatabase.php │ └── VerbosePostDownloadTask.php ├── ProjectTemplate │ ├── Console │ │ └── Commands │ │ │ └── UpdateTemplateCommand.php │ ├── DownloadedLaravelRelease.php │ ├── LaravelDownloader.php │ ├── ProjectTemplateService.php │ ├── ProjectTemplateServiceProvider.php │ ├── README.md │ └── TemplateStorage.php ├── ProjectTemplateCustomization │ ├── ProjectTemplateCustomizer.php │ ├── README.md │ └── Resolver │ │ ├── ComposerPackagesToInstallResolver.php │ │ ├── NpmPackagesToInstallResolver.php │ │ └── SailServiceResolver.php ├── Readme │ ├── MarkdownRenderer.php │ ├── ReadmeArchiveManipulator.php │ ├── ReadmeGenerator.php │ ├── ReadmeServiceProvider.php │ ├── Support │ │ └── Str.php │ └── resources │ │ └── templates │ │ └── README.blade.php ├── Schedule │ ├── Http │ │ └── Controllers │ │ │ └── ScheduleRunController.php │ └── ScheduleServiceProvider.php ├── SourceCodeManipulation │ └── Perl │ │ ├── AddTrait.php │ │ └── Perl.php ├── Statistics │ ├── Statistics.php │ ├── StatisticsService.php │ └── StatisticsSummary.php └── Support │ ├── Enum │ └── EmulatesEnum.php │ └── FileSystem │ └── Path.php ├── fly.toml ├── package-lock.json ├── package.json ├── phpstan.neon.dist ├── phpunit.xml ├── postcss.config.js ├── public ├── .htaccess ├── favicon.ico ├── img │ ├── logos │ │ ├── database │ │ │ ├── mariadb.svg │ │ │ ├── mysql.svg │ │ │ └── postgres.svg │ │ └── starter │ │ │ ├── breeze.svg │ │ │ ├── jetstream.svg │ │ │ └── laravel.svg │ └── og │ │ └── initializer-for-laravel.png ├── index.php ├── robots.txt └── web.config ├── resources ├── css │ └── app.css ├── js │ ├── app.js │ └── shareable-url │ │ ├── computeSharingUrl.js │ │ ├── extractFormValues.js │ │ ├── filters.js │ │ └── shareable-url.js ├── lang │ └── en │ │ ├── auth.php │ │ ├── pagination.php │ │ ├── passwords.php │ │ └── validation.php └── views │ ├── components │ ├── button │ │ └── big.blade.php │ ├── database-option.blade.php │ ├── first-party-package │ │ ├── choice.blade.php │ │ ├── option-group.blade.php │ │ └── option.blade.php │ ├── form-control │ │ ├── checkbox.blade.php │ │ ├── container.blade.php │ │ ├── group.blade.php │ │ └── radio.blade.php │ ├── form-section.blade.php │ ├── head │ │ └── opengraph-tags.blade.php │ ├── icons │ │ ├── beaker.blade.php │ │ ├── bell.blade.php │ │ ├── bolt.blade.php │ │ ├── code.blade.php │ │ ├── credit-card.blade.php │ │ ├── database.blade.php │ │ ├── dots.blade.php │ │ ├── download.blade.php │ │ ├── home.blade.php │ │ ├── info.blade.php │ │ ├── lock.blade.php │ │ ├── mail.blade.php │ │ ├── megaphone.blade.php │ │ ├── search.blade.php │ │ ├── storage.blade.php │ │ └── template.blade.php │ ├── inline-radio.blade.php │ ├── layout │ │ ├── default.blade.php │ │ └── header.blade.php │ ├── link.blade.php │ ├── metadata │ │ └── package-name-input.blade.php │ ├── nav │ │ └── link.blade.php │ ├── optional.blade.php │ ├── radio-option-none.blade.php │ ├── radio-option.blade.php │ ├── sail │ │ ├── choice.blade.php │ │ └── option.blade.php │ ├── sponsor-button.blade.php │ ├── tag.blade.php │ ├── tags │ │ ├── community.blade.php │ │ └── sail.blade.php │ └── validation │ │ └── errors.blade.php │ ├── pages │ ├── about.blade.php │ └── welcome.blade.php │ └── partials │ └── form-section │ ├── authentication.blade.php │ ├── broadcasting.blade.php │ ├── cache.blade.php │ ├── database.blade.php │ ├── dev-tools.blade.php │ ├── mail.blade.php │ ├── notifications.blade.php │ ├── payments.blade.php │ ├── project-metadata.blade.php │ ├── queue.blade.php │ ├── search.blade.php │ ├── starter-kit.blade.php │ ├── storage.blade.php │ └── testing.blade.php ├── storage ├── app │ └── .gitignore ├── debugbar │ └── .gitignore ├── framework │ ├── .gitignore │ ├── cache │ │ ├── .gitignore │ │ └── data │ │ │ └── .gitignore │ ├── sessions │ │ └── .gitignore │ ├── testing │ │ └── .gitignore │ └── views │ │ └── .gitignore └── logs │ └── .gitignore ├── tailwind.config.js ├── tests ├── CreatesApplication.php ├── Feature │ └── Domains │ │ ├── Composer │ │ ├── ComposerJsonFileTest.php │ │ ├── ComposerJsonFixtures.php │ │ └── VersionResolvingTest.php │ │ ├── Packagist │ │ └── PackagistApiClientTest.php │ │ ├── ProjectCreation │ │ ├── ArchiveManipulation │ │ │ ├── InstallScriptGeneratorTest.php │ │ │ └── ReadmeGeneratorTest.php │ │ ├── CreateProjectFormFixtures.php │ │ └── Http │ │ │ └── Request │ │ │ └── CreateProjectRequestTest.php │ │ ├── ProjectTemplate │ │ ├── Console │ │ │ └── Commands │ │ │ │ └── UpdateTemplateCommandTest.php │ │ ├── Laravel862Package.php │ │ ├── LaravelDownloaderTest.php │ │ └── TemplateStorageTest.php │ │ ├── ProjectTemplateCustomization │ │ └── ArchiveManipulation │ │ │ ├── AllArchiveManipulatorsCanBeResolvedTest.php │ │ │ ├── ComposerJsonGeneratorTest.php │ │ │ └── FlysystemAdjusterTest.php │ │ ├── Statistics │ │ └── StatisticsTest.php │ │ └── Support │ │ └── PathTest.php ├── Integration │ └── ActualTest.php ├── TestCase.php ├── Unit │ └── Domains │ │ └── Markdown │ │ └── RendererTest.php └── resources │ └── fixtures │ └── config │ └── filesystem │ ├── both.php │ ├── default.php │ ├── ftp-only.php │ └── sftp-only.php └── vite.config.js /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // https://aka.ms/devcontainer.json 2 | { 3 | "name": "Existing Docker Compose (Extend)", 4 | "dockerComposeFile": [ 5 | "../docker-compose.yml" 6 | ], 7 | "remoteEnv": { 8 | "WWWGROUP": "1000", 9 | "WWWUSER": "1000" 10 | }, 11 | "service": "laravel.test", 12 | "workspaceFolder": "/var/www/html", 13 | "settings": {}, 14 | "extensions": [ 15 | "mikestead.dotenv", 16 | "amiralizadeh9480.laravel-extra-intellisense", 17 | "ryannaddy.laravel-artisan", 18 | "onecentlin.laravel5-snippets", 19 | "onecentlin.laravel-blade", 20 | "emallin.phpunit", 21 | "editorconfig.editorconfig", 22 | "bmewburn.vscode-intelephense-client" 23 | ], 24 | "remoteUser": "sail", 25 | "forwardPorts": [8000, 80], 26 | "runServices": ["laravel.test"], 27 | "postCreateCommand": "npm install --no-save && composer install && cp .env.example .env && php artisan key:generate && php artisan initializer:update-template && npm run dev", 28 | // "shutdownAction": "none", 29 | } 30 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | # excludes from the docker image/build 2 | 3 | # 1. Ignore Laravel-specific files we don't need 4 | bootstrap/cache/* 5 | storage/framework/cache/* 6 | storage/framework/sessions/* 7 | storage/framework/views/* 8 | storage/logs/* 9 | *.env* 10 | .rr.yml 11 | rr 12 | vendor 13 | 14 | # 2. Ignore common files/directories we don't need 15 | fly.toml 16 | .vscode 17 | .idea 18 | **/*node_modules 19 | **.git 20 | **.gitignore 21 | **.gitattributes 22 | **.sass-cache 23 | **/*~ 24 | **/*.log 25 | **/.DS_Store 26 | **/Thumbs.db 27 | public/hot 28 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | insert_final_newline = true 7 | indent_style = space 8 | indent_size = 4 9 | trim_trailing_whitespace = true 10 | 11 | [*.blade.php] 12 | insert_final_newline = false 13 | 14 | [*.md] 15 | trim_trailing_whitespace = false 16 | 17 | [*.{yml,yaml}] 18 | indent_size = 2 19 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | APP_NAME="Initializer for Laravel" 2 | APP_ENV=local 3 | APP_KEY= 4 | APP_DEBUG=true 5 | APP_URL=http://localhost 6 | 7 | LOG_CHANNEL=stack 8 | LOG_LEVEL=debug 9 | 10 | DB_CONNECTION=mysql 11 | DB_HOST=127.0.0.1 12 | DB_PORT=3306 13 | DB_DATABASE=initializer 14 | DB_USERNAME=root 15 | DB_PASSWORD= 16 | 17 | BROADCAST_DRIVER=log 18 | CACHE_DRIVER=file 19 | QUEUE_CONNECTION=sync 20 | SESSION_DRIVER=file 21 | SESSION_LIFETIME=120 22 | 23 | MEMCACHED_HOST=127.0.0.1 24 | 25 | REDIS_HOST=127.0.0.1 26 | REDIS_PASSWORD=null 27 | REDIS_PORT=6379 28 | 29 | MAIL_MAILER=smtp 30 | MAIL_HOST=mailhog 31 | MAIL_PORT=1025 32 | MAIL_USERNAME=null 33 | MAIL_PASSWORD=null 34 | MAIL_ENCRYPTION=null 35 | MAIL_FROM_ADDRESS=null 36 | MAIL_FROM_NAME="${APP_NAME}" 37 | 38 | AWS_ACCESS_KEY_ID= 39 | AWS_SECRET_ACCESS_KEY= 40 | AWS_DEFAULT_REGION=us-east-1 41 | AWS_BUCKET= 42 | 43 | PUSHER_APP_ID= 44 | PUSHER_APP_KEY= 45 | PUSHER_APP_SECRET= 46 | PUSHER_APP_CLUSTER=mt1 47 | 48 | MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" 49 | MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" 50 | 51 | WWWGROUP=1000 52 | WWWUSER=1000 53 | -------------------------------------------------------------------------------- /.fly/entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # Run user scripts, if they exist 4 | for f in /var/www/html/.fly/scripts/*.sh; do 5 | # Bail out this loop if any script exits with non-zero status code 6 | bash "$f" || break 7 | done 8 | chown -R www-data:www-data /var/www/html 9 | 10 | if [ $# -gt 0 ]; then 11 | # If we passed a command, run it as root 12 | exec "$@" 13 | else 14 | exec supervisord -c /etc/supervisor/supervisord.conf 15 | fi 16 | -------------------------------------------------------------------------------- /.fly/scripts/caches.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | /usr/bin/php /var/www/html/artisan config:cache --no-ansi -q 4 | /usr/bin/php /var/www/html/artisan route:cache --no-ansi -q 5 | /usr/bin/php /var/www/html/artisan view:cache --no-ansi -q 6 | 7 | /usr/bin/php /var/www/html/artisan migrate --force --no-ansi -q 8 | /usr/bin/php /var/www/html/artisan initializer:update-template --no-ansi -q 9 | /usr/bin/php /var/www/html/artisan google-fonts:fetch --no-ansi -q 10 | /usr/bin/php /var/www/html/artisan storage:link --no-ansi -q 11 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.css linguist-vendored 3 | *.scss linguist-vendored 4 | *.js linguist-vendored 5 | CHANGELOG.md export-ignore 6 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: NiclasVanEyk # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement, new feature 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/initialization-error.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Initialization Error 3 | about: An error occurred while running `./initialize` 4 | title: '' 5 | labels: bug, ./initialize 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe The Bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **Chosen Packages & Configuration** 14 | 1. Laravel Starter 15 | 2. Postgres Database 16 | 3. ... 17 | 18 | **Command Line Output** 19 | ``` 20 | 21 | ``` 22 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/other.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Other 3 | about: Anything else 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: "monthly" 7 | 8 | - package-ecosystem: "npm" 9 | directory: "/" 10 | schedule: 11 | interval: "monthly" 12 | 13 | - package-ecosystem: "composer" 14 | directory: "/" 15 | schedule: 16 | interval: "monthly" 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /public/hot 3 | /public/storage 4 | /public/css 5 | /public/js 6 | /public/mix-manifest.json 7 | /storage/*.key 8 | /vendor 9 | .env 10 | .env.backup 11 | .phpunit.result.cache 12 | docker-compose.override.yml 13 | Homestead.json 14 | Homestead.yaml 15 | npm-debug.log 16 | yarn-error.log 17 | -------------------------------------------------------------------------------- /.styleci.yml: -------------------------------------------------------------------------------- 1 | risky: false 2 | version: 8.1 3 | preset: laravel 4 | disabled: 5 | - no_unused_imports 6 | finder: 7 | exclude: 8 | - "modules" 9 | - "node_modules" 10 | - "nova" 11 | - "nova-components" 12 | - "storage" 13 | - "spark" 14 | - "vendor" 15 | name: "*.php" 16 | not-name: 17 | - index.php 18 | - server.php 19 | - "*.blade.php" 20 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | 2 | The MIT License (MIT) 3 | 4 | Copyright (c) Niclas van Eyk 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /app/AppServiceProvider.php: -------------------------------------------------------------------------------- 1 | app->environment('production')) { 13 | URL::forceScheme('https'); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/ExceptionHandler.php: -------------------------------------------------------------------------------- 1 | reportable(function (Throwable $exception): void { 13 | if (app()->bound('sentry') && $this->shouldReport($exception)) { 14 | app('sentry')->captureException($exception); 15 | } 16 | }); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/SentryTracingSampler.php: -------------------------------------------------------------------------------- 1 | getParentSampled()) { 21 | return 1.0; 22 | } 23 | 24 | // Default sample rate for all other transactions 25 | return config('sentry.traces_sample_rate', 0.0); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/TrustProxies.php: -------------------------------------------------------------------------------- 1 | |string|null 14 | */ 15 | protected $proxies = '*'; 16 | 17 | /** 18 | * The headers that should be used to detect proxies. 19 | * 20 | * @var int 21 | */ 22 | protected $headers = 23 | Request::HEADER_X_FORWARDED_FOR | 24 | Request::HEADER_X_FORWARDED_HOST | 25 | Request::HEADER_X_FORWARDED_PORT | 26 | Request::HEADER_X_FORWARDED_PROTO | 27 | Request::HEADER_X_FORWARDED_AWS_ELB; 28 | } 29 | -------------------------------------------------------------------------------- /app/helpers.php: -------------------------------------------------------------------------------- 1 | has('preset') && $default; 7 | 8 | return old($parameter, request()->has($parameter) || $fallback); 9 | } 10 | } 11 | 12 | if (! function_exists('option_selected')) { 13 | function option_selected(string $parameter, mixed $default): mixed 14 | { 15 | $fallback = request()->has('preset') ? 'none' : $default; 16 | $default = request()->has($parameter) ? request($parameter) : $fallback; 17 | 18 | return old($parameter, $default); 19 | } 20 | } 21 | 22 | if (! function_exists('enum_option_selected')) { 23 | /** 24 | * @template E of BackedEnum 25 | * 26 | * @param string $parameter 27 | * @param E $default 28 | * @return E 29 | */ 30 | function enum_option_selected(string $parameter, BackedEnum $default): BackedEnum 31 | { 32 | $fallback = request()->has('preset') 33 | ? $default::from('none') 34 | : $default; 35 | 36 | $value = request()->has($parameter) 37 | ? request($parameter) 38 | : old($parameter); 39 | 40 | return $fallback::tryFrom($value) ?? $fallback; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /bootstrap/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /config/google-fonts.php: -------------------------------------------------------------------------------- 1 | [ 5 | 'default' => 'https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap', 6 | ], 7 | ]; 8 | -------------------------------------------------------------------------------- /config/view.php: -------------------------------------------------------------------------------- 1 | [ 17 | resource_path('views'), 18 | ], 19 | 20 | /* 21 | |-------------------------------------------------------------------------- 22 | | Compiled View Path 23 | |-------------------------------------------------------------------------- 24 | | 25 | | This option determines where all the compiled Blade templates will be 26 | | stored for your application. Typically, this is within the storage 27 | | directory. However, as usual, you are free to change this value. 28 | | 29 | */ 30 | 31 | 'compiled' => env( 32 | 'VIEW_COMPILED_PATH', 33 | realpath(storage_path('framework/views')) 34 | ), 35 | 36 | ]; 37 | -------------------------------------------------------------------------------- /database/migrations/2022_01_25_225659_create_statistics_table.php: -------------------------------------------------------------------------------- 1 | id(); 13 | $table->string('starter'); 14 | $table->string('database'); 15 | $table->string('cache'); 16 | $table->string('queue'); 17 | $table->string('search'); 18 | $table->string('cashier'); 19 | $table->timestamps(); 20 | }); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /docker/8.0/php.ini: -------------------------------------------------------------------------------- 1 | [PHP] 2 | post_max_size = 100M 3 | upload_max_filesize = 100M 4 | variables_order = EGPCS 5 | -------------------------------------------------------------------------------- /docker/8.0/start-container: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [ ! -z "$WWWUSER" ]; then 4 | usermod -u $WWWUSER sail 5 | fi 6 | 7 | if [ ! -d /.composer ]; then 8 | mkdir /.composer 9 | fi 10 | 11 | chmod -R ugo+rw /.composer 12 | 13 | if [ $# -gt 0 ]; then 14 | exec gosu $WWWUSER "$@" 15 | else 16 | exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf 17 | fi 18 | -------------------------------------------------------------------------------- /docker/8.0/supervisord.conf: -------------------------------------------------------------------------------- 1 | [supervisord] 2 | nodaemon=true 3 | user=root 4 | logfile=/var/log/supervisor/supervisord.log 5 | pidfile=/var/run/supervisord.pid 6 | 7 | [program:php] 8 | command=/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan serve --host=0.0.0.0 --port=80 9 | user=sail 10 | environment=LARAVEL_SAIL="1" 11 | stdout_logfile=/dev/stdout 12 | stdout_logfile_maxbytes=0 13 | stderr_logfile=/dev/stderr 14 | stderr_logfile_maxbytes=0 15 | -------------------------------------------------------------------------------- /docker/8.1/php.ini: -------------------------------------------------------------------------------- 1 | [PHP] 2 | post_max_size = 100M 3 | upload_max_filesize = 100M 4 | variables_order = EGPCS 5 | -------------------------------------------------------------------------------- /docker/8.1/start-container: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [ ! -z "$WWWUSER" ]; then 4 | usermod -u $WWWUSER sail 5 | fi 6 | 7 | if [ ! -d /.composer ]; then 8 | mkdir /.composer 9 | fi 10 | 11 | chmod -R ugo+rw /.composer 12 | 13 | if [ $# -gt 0 ]; then 14 | exec gosu $WWWUSER "$@" 15 | else 16 | exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf 17 | fi 18 | -------------------------------------------------------------------------------- /docker/8.1/supervisord.conf: -------------------------------------------------------------------------------- 1 | [supervisord] 2 | nodaemon=true 3 | user=root 4 | logfile=/var/log/supervisor/supervisord.log 5 | pidfile=/var/run/supervisord.pid 6 | 7 | [program:php] 8 | command=/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan serve --host=0.0.0.0 --port=80 9 | user=sail 10 | environment=LARAVEL_SAIL="1" 11 | stdout_logfile=/dev/stdout 12 | stdout_logfile_maxbytes=0 13 | stderr_logfile=/dev/stderr 14 | stderr_logfile_maxbytes=0 15 | -------------------------------------------------------------------------------- /docker/8.2/php.ini: -------------------------------------------------------------------------------- 1 | [PHP] 2 | post_max_size = 100M 3 | upload_max_filesize = 100M 4 | variables_order = EGPCS 5 | -------------------------------------------------------------------------------- /docker/8.2/start-container: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [ ! -z "$WWWUSER" ]; then 4 | usermod -u $WWWUSER sail 5 | fi 6 | 7 | if [ ! -d /.composer ]; then 8 | mkdir /.composer 9 | fi 10 | 11 | chmod -R ugo+rw /.composer 12 | 13 | if [ $# -gt 0 ]; then 14 | exec gosu $WWWUSER "$@" 15 | else 16 | exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf 17 | fi 18 | -------------------------------------------------------------------------------- /docker/8.2/supervisord.conf: -------------------------------------------------------------------------------- 1 | [supervisord] 2 | nodaemon=true 3 | user=root 4 | logfile=/var/log/supervisor/supervisord.log 5 | pidfile=/var/run/supervisord.pid 6 | 7 | [program:php] 8 | command=/usr/bin/php -d variables_order=EGPCS /var/www/html/artisan serve --host=0.0.0.0 --port=80 9 | user=sail 10 | environment=LARAVEL_SAIL="1" 11 | stdout_logfile=/dev/stdout 12 | stdout_logfile_maxbytes=0 13 | stderr_logfile=/dev/stderr 14 | stderr_logfile_maxbytes=0 15 | -------------------------------------------------------------------------------- /domains/ArchiveManipulation/ArchiveManipulatorResolver.php: -------------------------------------------------------------------------------- 1 | 25 | * 26 | * @throws MissingArchiveManipulatorInterfaceException 27 | */ 28 | public function resolve(): Collection 29 | { 30 | /** @var array $manipulators */ 31 | $manipulators = $this->container->tagged(ArchiveManipulator::class); 32 | 33 | return collect($manipulators)->each(function ($class) { 34 | $this->ensureImplementsArchiveManipulatorInterface($class); 35 | }); 36 | } 37 | 38 | private function ensureImplementsArchiveManipulatorInterface( 39 | mixed $class, 40 | ): void { 41 | if (! $class instanceof ArchiveManipulator) { 42 | throw new MissingArchiveManipulatorInterfaceException($class); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /domains/ArchiveManipulation/MissingArchiveManipulatorInterfaceException.php: -------------------------------------------------------------------------------- 1 | app->tag(Arr::wrap($manipulators), ArchiveManipulator::class); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /domains/Composer/ComposerDependency.php: -------------------------------------------------------------------------------- 1 | versionConstraint() !== null; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /domains/Composer/ComposerServiceProvider.php: -------------------------------------------------------------------------------- 1 | registerArchiveManipulator( 16 | ComposerJsonArchiveManipulator::class 17 | ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /domains/Composer/InlineComposerDependency.php: -------------------------------------------------------------------------------- 1 | id; 19 | } 20 | 21 | public function packageId(): string 22 | { 23 | return $this->id; 24 | } 25 | 26 | public function name(): string 27 | { 28 | return $this->name; 29 | } 30 | 31 | public function description(): string 32 | { 33 | return $this->description; 34 | } 35 | 36 | public function href(): ?string 37 | { 38 | return $this->href; 39 | } 40 | 41 | public function isDevDependency(): bool 42 | { 43 | return $this->isDevDependency; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /domains/Composer/LogIO.php: -------------------------------------------------------------------------------- 1 | packageId()}'!"); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /domains/Composer/PackageName.php: -------------------------------------------------------------------------------- 1 | getEntryContents( 19 | 'composer.json', 20 | ); 21 | $defaultComposerJson = ComposerJsonFile::fromString( 22 | $defaultComposerJsonContents, 23 | ); 24 | 25 | $customizedComposerJsonContents = $this->generator->render( 26 | $form, 27 | $defaultComposerJson, 28 | ); 29 | $archive->addFromString( 30 | 'composer.json', 31 | $customizedComposerJsonContents, 32 | ); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /domains/ConfigAdjustment/CacheAdjuster.php: -------------------------------------------------------------------------------- 1 | replaceEnvExample($archive, [ 26 | 'REDIS_HOST=127.0.0.1' => 'REDIS_HOST=redis', 27 | ]); 28 | break; 29 | 30 | case MemcacheDCacheDriver::class: 31 | $this->replaceEnvExample($archive, [ 32 | 'MEMCACHED_HOST=127.0.0.1' => 'MEMCACHED_HOST=memcached', 33 | ]); 34 | break; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /domains/ConfigAdjustment/ConfigAdjustmentArchiveManipulator.php: -------------------------------------------------------------------------------- 1 | database->adjustDefaults($archive, $form->database->database); 23 | $this->cache->adjustDefaults($archive, $form->cache->driver); 24 | $this->broadcasting->adjustDefaults($archive, $form->broadcasting); 25 | $this->search->adjustDefaults($archive, $form->search); 26 | $this->flysystem->adjustDefaults($archive, $form->storage); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /domains/ConfigAdjustment/ConfigAdjustmentServiceProvider.php: -------------------------------------------------------------------------------- 1 | registerArchiveManipulator( 15 | ConfigAdjustmentArchiveManipulator::class, 16 | ); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /domains/CreateProjectForm/Components/Logo.php: -------------------------------------------------------------------------------- 1 | group(function () { 17 | Routes::register(); 18 | }); 19 | 20 | $this->loadStarterKitComponents(); 21 | } 22 | 23 | private function loadStarterKitComponents(): void 24 | { 25 | $this->loadViewsFrom( 26 | __DIR__.'/resources/views/starter-kit', 27 | 'starter-kit' 28 | ); 29 | 30 | Blade::componentNamespace( 31 | Str::namespace(Selector::class), 32 | 'starter-kit' 33 | ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /domains/CreateProjectForm/Http/Controllers/PermalinkController.php: -------------------------------------------------------------------------------- 1 | all()) 17 | ->only(CreateProjectRequestParameter::values()) 18 | ->except([ 19 | // These are very likely to differ between projects, so we don't 20 | // include / support them to be read from the query params 21 | CreateProjectRequestParameter::PROJECT, 22 | CreateProjectRequestParameter::DESCRIPTION, 23 | ]) 24 | ->toArray(); 25 | 26 | return redirect(route('root', $parameters)); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /domains/CreateProjectForm/Http/Controllers/ShowFormController.php: -------------------------------------------------------------------------------- 1 | currentVersion(); 14 | 15 | if (Str::startsWith($currentLaravelVersion, 'v')) { 16 | $currentLaravelVersion = Str::substr($currentLaravelVersion, 1); 17 | } 18 | 19 | return view('pages.welcome', [ 20 | 'currentLaravelVersion' => $currentLaravelVersion, 21 | ]); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /domains/CreateProjectForm/Http/Request/CreateProjectRequest/CreateProjectRequestParameterLabel.php: -------------------------------------------------------------------------------- 1 | 18 | */ 19 | public static array $map = [ 20 | Parameter::VENDOR => self::VENDOR, 21 | Parameter::PROJECT => self::PROJECT, 22 | Parameter::DESCRIPTION => self::DESCRIPTION, 23 | ]; 24 | } 25 | -------------------------------------------------------------------------------- /domains/CreateProjectForm/Http/Request/CreateProjectRequest/NormalizesInputs.php: -------------------------------------------------------------------------------- 1 | get('/', ShowFormController::class); 21 | Route::name('about')->get('about', function (StatisticsService $statistics) { 22 | return view('pages.about', [ 23 | 'statistics' => $statistics->summary(), 24 | ]); 25 | }); 26 | 27 | Route::name('permalink') 28 | ->post('permalink', PermalinkController::class); 29 | 30 | RateLimiter::for('create-project', function (Request $request) { 31 | return Limit::perMinute(20)->by($request->ip() ?? 'unknown'); 32 | }); 33 | 34 | Route::name('create-project') 35 | ->middleware('throttle:create-project') 36 | ->post('create-project', CreateProjectController::class); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /domains/CreateProjectForm/Sections/Authentication.php: -------------------------------------------------------------------------------- 1 | new RedisCacheDriver(), 21 | CacheOption::MEMCACHED => new MemcacheDCacheDriver(), 22 | CacheOption::NONE => null, 23 | default => null, 24 | }; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /domains/CreateProjectForm/Sections/Cache/CacheDriver.php: -------------------------------------------------------------------------------- 1 | driver) { 22 | default => null, 23 | MailDriverOption::MAILGUN => new MailgunMailer(), 24 | MailDriverOption::POSTMARK => new PostmarkMailer(), 25 | MailDriverOption::SES => new AwsSdk(), 26 | }; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /domains/CreateProjectForm/Sections/Mail/MailDriverOption.php: -------------------------------------------------------------------------------- 1 | vendorName/$this->projectName"; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /domains/CreateProjectForm/Sections/Metadata/PhpVersion.php: -------------------------------------------------------------------------------- 1 | new CashierStripeDriver(), 29 | CashierDriverOption::PADDLE => new CashierPaddleDriver(), 30 | CashierDriverOption::MOLLIE => new CashierMollieDriver(), 31 | default => null, 32 | }; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /domains/CreateProjectForm/Sections/Queue.php: -------------------------------------------------------------------------------- 1 | new RedisQueueDriver(), 23 | QueueDriverOption::BEANSTALKD => new BeanstalkdQueueDriver(), 24 | QueueDriverOption::SQS => new SqsQueueDriver(), 25 | default => null, 26 | }; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /domains/CreateProjectForm/Sections/Queue/BeanstalkdQueueDriver.php: -------------------------------------------------------------------------------- 1 | 10 |

11 | The default starter kit without any authentication scaffolding. 12 |

13 | 14 | -------------------------------------------------------------------------------- /domains/CreateProjectForm/resources/views/starter-kit/starter-option.blade.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /domains/CreateProjectForm/resources/views/starter-kit/starter-selector.blade.php: -------------------------------------------------------------------------------- 1 | @php 2 | 3 | use Domains\CreateProjectForm\Http\Request\CreateProjectRequest\CreateProjectRequestParameter as P; 4 | 5 | $model = P::STARTER; 6 | $laravel = Domains\Laravel\StarterKit\StarterKit::LARAVEL; 7 | $starter = old(P::STARTER, request(P::STARTER, $laravel)) 8 | @endphp 9 | 10 |
15 | 16 | 17 | 18 |
19 | -------------------------------------------------------------------------------- /domains/DockerImages/DockerImagesServiceProvider.php: -------------------------------------------------------------------------------- 1 | app->runningInConsole()) { 13 | $this->commands([UpdateSailImages::class]); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /domains/InitializationScript/InitializationScriptArchiveManipulator.php: -------------------------------------------------------------------------------- 1 | generator->scriptName(); 18 | $archive->addFromString($script, $this->generator->render($form)); 19 | 20 | // Make sure the script is executable 21 | $archive->getEntry($script)->setUnixMode(0100754); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /domains/InitializationScript/InitializationScriptGenerator.php: -------------------------------------------------------------------------------- 1 | view->make('template::initialize', [ 24 | 'taskRenderer' => $this->taskRenderer, 25 | 'groups' => $this->postDownloadTaskGroupCreator->fromForm($form), 26 | 'links' => $this->postInitializationLinkResolver->links($form), 27 | 'initializationScript' => $this->scriptName(), 28 | 'githubIssueLink' => 'https://github.com/NiclasvanEyk/initializer-for-laravel/issues/new', 29 | ])->render(); 30 | } 31 | 32 | public function scriptName(): string 33 | { 34 | return 'initialize'; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /domains/InitializationScript/InitializationScriptServiceProvider.php: -------------------------------------------------------------------------------- 1 | loadViewsFrom(__DIR__.'/resources/templates', 'template'); 19 | 20 | $this->registerBladeComponentsNextTo(Banner::class, 'shell'); 21 | $this->registerBladeComponentsNextTo(WelcomeBanner::class, 'initialize'); 22 | 23 | $this->registerArchiveManipulator( 24 | InitializationScriptArchiveManipulator::class, 25 | ); 26 | } 27 | 28 | /** 29 | * Registers all Blade components directly next to $exampleComponent under 30 | * the $prefix namespace. 31 | */ 32 | private function registerBladeComponentsNextTo( 33 | string $exampleComponent, 34 | string $prefix, 35 | ): void { 36 | Blade::componentNamespace(Str::namespace($exampleComponent), $prefix); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /domains/InitializationScript/README.md: -------------------------------------------------------------------------------- 1 | # InitializationScript 2 | 3 | This is the place where the `initialize` script is generated. Note that this mainly represents the _static_ part of the initialization script. Everything that depends on inputs from the form, such as what packages to install, is computed in the [PostDownloadTaskGroupCreator](../PostDownload/PostDownloadTaskGroupCreator.php). 4 | 5 | The generation is done by utilizing [Laravels Blade Components](https://laravel.com/docs/blade#components). Those are divided into 6 | - [**Shell**](./View/Components/Shell) – Generic shell components like banners, bold text, etc. 7 | - [**Initialize**](./View/Components/Initialize) – Components that represent parts of the `initialize` script, what happens when an error occurs, how a [TaskGroup](../PostDownload/PostDownloadTaskGroup.php) should be displayed, or the [welcome banner](./View/Components/Initialize/WelcomeBanner.php) 8 | 9 | The resulting template for the script is quite short and can be found under [`./resources/templates/initialize.blade.php`](./resources/templates/initialize.blade.php) 10 | -------------------------------------------------------------------------------- /domains/InitializationScript/View/Components/Initialize/Cleanup.php: -------------------------------------------------------------------------------- 1 | .*//gs' README.md 28 | BLADE; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /domains/InitializationScript/View/Components/Initialize/DoneBanner.php: -------------------------------------------------------------------------------- 1 | 26 | 27 | You can now have a look at README.md, for further instructions, guides 28 | and links to the installed components. 29 | 30 | Some helpful links: 31 | @foreach($links as $link) 32 | - {{$link->title}} {{ $link->href }} 33 | @endforeach 34 | 35 | echo ''; 36 | BLADE; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /domains/InitializationScript/View/Components/Initialize/EnsureDockerIsRunning.php: -------------------------------------------------------------------------------- 1 | /dev/null 2>&1; then 16 | echo -e "Docker is not running." >&2; 17 | exit 1; 18 | fi 19 | SHELL; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /domains/InitializationScript/View/Components/Initialize/TaskGroup.php: -------------------------------------------------------------------------------- 1 | title()" /> 27 | echo ''; 28 | 29 | @foreach($group->tasks() as $task) 30 | {!! $renderer->announce($task) !!} 31 | {!! $renderer->execute($task) !!} 32 | @endforeach 33 | BLADE; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /domains/InitializationScript/View/Components/Initialize/WelcomeBanner.php: -------------------------------------------------------------------------------- 1 | 17 | 18 | This script will complete the rest of the setup needed to install the 19 | chosen components into your fresh application. This might require 20 | downloading Docker containers or requiring packages via composer 21 | multiple times, so it can take a while to complete. 22 | 23 | BLADE; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /domains/InitializationScript/View/Components/Shell/Banner.php: -------------------------------------------------------------------------------- 1 | error ? ';31' : ''; 19 | 20 | return <<packageId(); 15 | } 16 | 17 | public function packageId(): string 18 | { 19 | $package = defined('static::REPOSITORY_KEY') 20 | ? static::REPOSITORY_KEY 21 | : $this->packageName(); 22 | 23 | return "laravel/$package"; 24 | } 25 | 26 | public function packageName(): string 27 | { 28 | return Str::lower(class_basename(static::class)); 29 | } 30 | 31 | public function name(): string 32 | { 33 | return Str::ucfirst($this->packageName()); 34 | } 35 | 36 | public function href(): string 37 | { 38 | return self::laravelDocsHref($this->packageName()); 39 | } 40 | 41 | public static function laravelDocsHref(string $path): string 42 | { 43 | return "https://laravel.com/docs/$path"; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /domains/Laravel/ComposerPackages/Packages/CashierMollie.php: -------------------------------------------------------------------------------- 1 | [AddTrait::toUserModel('\\Laravel\\Cashier\\Billable')], 46 | ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /domains/Laravel/ComposerPackages/Packages/CashierPaddle.php: -------------------------------------------------------------------------------- 1 | [AddTrait::toUserModel('\\Laravel\\Paddle\\Billable')], 41 | ); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /domains/Laravel/ComposerPackages/Packages/CashierStripe.php: -------------------------------------------------------------------------------- 1 | [AddTrait::toUserModel('\\Laravel\\Cashier\\Billable')], 46 | ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /domains/Laravel/ComposerPackages/Packages/Dusk.php: -------------------------------------------------------------------------------- 1 | ["$artisan dusk:install"], 33 | ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /domains/Laravel/ComposerPackages/Packages/Envoy.php: -------------------------------------------------------------------------------- 1 | ["$artisan horizon:install"], 33 | ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /domains/Laravel/ComposerPackages/Packages/Pail.php: -------------------------------------------------------------------------------- 1 | [ 27 | new WaitForDatabase($artisan), 28 | "$artisan migrate", 29 | "$artisan passport:install", 30 | AddTrait::toUserModel('\\Laravel\\Passport\\HasApiTokens'), 31 | ], 32 | ); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /domains/Laravel/ComposerPackages/Packages/Pennant.php: -------------------------------------------------------------------------------- 1 | [ 25 | "$artisan vendor:publish --provider=\"Laravel\Pennant\PennantServiceProvider\"", 26 | new WaitForDatabase($artisan), 27 | "$artisan migrate", 28 | ], 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /domains/Laravel/ComposerPackages/Packages/Sanctum.php: -------------------------------------------------------------------------------- 1 | Always included.'; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /domains/Laravel/ComposerPackages/Packages/Scout.php: -------------------------------------------------------------------------------- 1 | [ 28 | "$artisan --no-interaction vendor:publish --provider=\"Laravel\Scout\ScoutServiceProvider\"", 29 | ], 30 | ); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /domains/Laravel/ComposerPackages/Packages/Socialite.php: -------------------------------------------------------------------------------- 1 | value; 13 | } 14 | 15 | public function packageId(): string 16 | { 17 | return 'ably/ably-php'; 18 | } 19 | 20 | public function name(): string 21 | { 22 | return 'Ably'; 23 | } 24 | 25 | public function description(): string 26 | { 27 | return 'The platform to power synchronized digital experiences in realtime.'; 28 | } 29 | 30 | public function href(): ?string 31 | { 32 | return 'https://ably.com'; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /domains/Laravel/RelatedPackages/Broadcasting/Pusher.php: -------------------------------------------------------------------------------- 1 | value; 13 | } 14 | 15 | public function packageId(): string 16 | { 17 | return 'pusher/pusher-php-server'; 18 | } 19 | 20 | public function name(): string 21 | { 22 | return 'Pusher'; 23 | } 24 | 25 | public function description(): string 26 | { 27 | return 'Realtime communication between servers, apps and devices'; 28 | } 29 | 30 | public function href(): ?string 31 | { 32 | return 'https://pusher.com'; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /domains/Laravel/RelatedPackages/Broadcasting/PusherJs.php: -------------------------------------------------------------------------------- 1 | value; 14 | } 15 | 16 | public function packageId(): string 17 | { 18 | return 'pusher-js'; 19 | } 20 | 21 | public function name(): string 22 | { 23 | return 'Pusher'; 24 | } 25 | 26 | public function description(): string 27 | { 28 | return 'Realtime communication between servers, apps and devices'; 29 | } 30 | 31 | public function href(): string 32 | { 33 | return 'https://pusher.com'; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /domains/Laravel/RelatedPackages/Broadcasting/Soketi.php: -------------------------------------------------------------------------------- 1 | value; 13 | } 14 | 15 | public function packageId(): string 16 | { 17 | return '@soketi/soketi'; 18 | } 19 | 20 | public function name(): string 21 | { 22 | return 'Soketi'; 23 | } 24 | 25 | public function description(): string 26 | { 27 | return 'Free, self-hosted, drop-in Pusher replacement implemented in Node.'; 28 | } 29 | 30 | public function href(): string 31 | { 32 | return 'https://soketi.app'; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /domains/Laravel/RelatedPackages/Database/DoctrineDbal.php: -------------------------------------------------------------------------------- 1 | value; 13 | } 14 | 15 | public function packageId(): string 16 | { 17 | return 'algolia/algoliasearch-client-php'; 18 | } 19 | 20 | public function name(): string 21 | { 22 | return 'Algolia'; 23 | } 24 | 25 | public function description(): string 26 | { 27 | return 'Powerful, hosted search API to create fast and relevant search & discovery.'; 28 | } 29 | 30 | public function href(): string 31 | { 32 | return 'https://www.algolia.com'; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /domains/Laravel/RelatedPackages/Testing/Pest.php: -------------------------------------------------------------------------------- 1 | packageId(); 17 | } 18 | 19 | public function packageId(): string 20 | { 21 | return 'pestphp/pest-plugin-laravel'; 22 | } 23 | 24 | public function name(): string 25 | { 26 | return 'Pest'; 27 | } 28 | 29 | public function description(): string 30 | { 31 | return 'A Testing Framework with a focus on simplicity.'; 32 | } 33 | 34 | public function href(): ?string 35 | { 36 | return 'https://pestphp.com'; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /domains/Laravel/Sail/DatabaseOption.php: -------------------------------------------------------------------------------- 1 | frontend, 20 | usesPest: $this->usesPest, 21 | ); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /domains/Laravel/StarterKit/BreezeFrontend.php: -------------------------------------------------------------------------------- 1 | name; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /domains/Laravel/StarterKit/Jetstream.php: -------------------------------------------------------------------------------- 1 | usesTeams, 21 | usesPest: $this->usesPest, 22 | frontend: $this->frontend, 23 | ); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /domains/Laravel/StarterKit/JetstreamFrontend.php: -------------------------------------------------------------------------------- 1 | name; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /domains/Laravel/StarterKit/Laravel.php: -------------------------------------------------------------------------------- 1 | $package 19 | */ 20 | public static function fromResponse(array $package): self 21 | { 22 | return new self( 23 | name: Arr::get($package, 'name', 'unknown'), 24 | version: Arr::get($package, 'version', 'unknown'), 25 | dist: PackageDist::fromRequest(Arr::get($package, 'dist', [])), 26 | ); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /domains/Packagist/Models/PackageDist.php: -------------------------------------------------------------------------------- 1 | $dist 19 | */ 20 | public static function fromRequest(array $dist): self 21 | { 22 | return new self( 23 | Arr::get($dist, 'type', ''), 24 | Arr::get($dist, 'url', ''), 25 | Arr::get($dist, 'reference', ''), 26 | ); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /domains/Packagist/PackagistApiClient.php: -------------------------------------------------------------------------------- 1 | request()->get("$this->baseUrl/$vendor/$package.json"); 27 | /** @var array> $packages */ 28 | $packages = $response->json("packages.$vendor/$package"); 29 | 30 | return collect($packages) 31 | ->map(fn (array $package) => Package::fromResponse($package)) 32 | ->all(); 33 | } 34 | 35 | public function downloadPackageDist(Package $package): Response 36 | { 37 | return $this->request()->get($package->dist->url); 38 | } 39 | 40 | protected function request(): PendingRequest 41 | { 42 | return new PendingRequest($this->httpClientFactory); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /domains/PostDownload/ClosurePostInstallTaskGroup.php: -------------------------------------------------------------------------------- 1 | theTitle; 20 | } 21 | 22 | public function tasks(): array 23 | { 24 | return call_user_func($this->theTasks); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /domains/PostDownload/PostDownloadTask.php: -------------------------------------------------------------------------------- 1 | $task->shellDescription(), 18 | $task instanceof PostDownloadTask => $task->shell(), 19 | default => (string) $task, 20 | }; 21 | 22 | return "echo {$this->escape($description)}"; 23 | } 24 | 25 | private function escape(string $shell): string 26 | { 27 | return escapeshellarg($shell); 28 | } 29 | 30 | /** 31 | * Return the shell string that should be executed. 32 | */ 33 | public function execute(PostDownloadTask|string $task): string 34 | { 35 | return is_string($task) ? $task : $task->shell(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /domains/PostDownload/PostInitializationLink.php: -------------------------------------------------------------------------------- 1 | href = $this->base.$href; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /domains/PostDownload/Tasks/AdjustPermissions.php: -------------------------------------------------------------------------------- 1 | /dev/null; then 30 | sudo chown -R $USER: . 31 | else 32 | echo -e "Please provide your password so we can make some final adjustments to your application's permissions." 33 | echo "" 34 | sudo chown -R $USER: . 35 | fi 36 | SHELL; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /domains/PostDownload/Tasks/InstallDevcontainer.php: -------------------------------------------------------------------------------- 1 | artisan sail:install --devcontainer --no-interaction", 22 | ]; 23 | } 24 | } 25 | 26 | namespace Domains\PostDownload\Tasks; 27 | -------------------------------------------------------------------------------- /domains/PostDownload/Tasks/MigrateDatabase.php: -------------------------------------------------------------------------------- 1 | artisan), 22 | "$this->artisan migrate", 23 | ]; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /domains/PostDownload/Tasks/SetupFrontend.php: -------------------------------------------------------------------------------- 1 | $packagesToInstall 14 | */ 15 | public function __construct( 16 | private string $npm, 17 | private Collection $packagesToInstall, 18 | ) { 19 | } 20 | 21 | public function title(): string 22 | { 23 | return 'Setup frontend'; 24 | } 25 | 26 | public function tasks(): array 27 | { 28 | $packages = $this->packagesToInstall 29 | ->map(fn (NpmDependency $package) => $package->packageId()) 30 | ->implode(' '); 31 | 32 | return [ 33 | "$this->npm install $packages", 34 | "$this->npm run build", 35 | ]; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /domains/PostDownload/Tasks/SetupPackages.php: -------------------------------------------------------------------------------- 1 | artisan breeze:install. 12 | */ 13 | class SetupPackages implements PostDownloadTaskGroup 14 | { 15 | /** 16 | * @param string $artisan 17 | * @param Collection $dependencies 18 | */ 19 | public function __construct( 20 | private string $artisan, 21 | private Collection $dependencies, 22 | ) { 23 | } 24 | 25 | public function title(): string 26 | { 27 | return 'Setup composer dependencies'; 28 | } 29 | 30 | /** @return array */ 31 | public function tasks(): array 32 | { 33 | return $this->dependencies 34 | ->filter(fn ($p) => $p instanceof ProvidesInstallationInstructions) 35 | ->map(fn (ProvidesInstallationInstructions $instructions) => $instructions->installationInstructions($this->artisan) 36 | ) 37 | ->all(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /domains/PostDownload/Tasks/StartSail.php: -------------------------------------------------------------------------------- 1 | sail up -d"; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /domains/PostDownload/Tasks/WaitForDatabase.php: -------------------------------------------------------------------------------- 1 | artisan tinker --execute 'try { DB::statement("select true"); echo("DB ready"); } catch (Throwable \$e) { exit(1); }' | grep -q "DB ready" || [ \$attempt -eq \$maxAttempts ]; do 26 | echo "Attempt \$attempt failed, retrying in \${sleepTime}s..."; 27 | ((attempt=attempt+1)); 28 | sleep \$sleepTime; 29 | done 30 | 31 | if [ "\$attempt" -eq "\$maxAttempts" ]; then 32 | echo "Could not connect to database after \$attempt attempts! Aborting..."; 33 | exit 1; 34 | fi 35 | 36 | echo "Database ready!" 37 | SHELL; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /domains/PostDownload/VerbosePostDownloadTask.php: -------------------------------------------------------------------------------- 1 | canBeUpdated()) { 17 | $this->logAndInfo('Local template storage does not need to be updated'); 18 | 19 | return; 20 | } 21 | 22 | $this->logAndInfo('Downloading latest release...'); 23 | $template->update(); 24 | 25 | $this->logAndInfo('Template was updated to the latest release!'); 26 | } 27 | 28 | private function logAndInfo(string $message): void 29 | { 30 | $this->info($message); 31 | Log::info($message); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /domains/ProjectTemplate/DownloadedLaravelRelease.php: -------------------------------------------------------------------------------- 1 | downloader->latestRelease(); 16 | $currentVersion = $this->storage->currentVersion(); 17 | 18 | return $latestRelease->version !== $currentVersion; 19 | } 20 | 21 | public function update(): void 22 | { 23 | $latestRelease = $this->downloader->latestRelease(); 24 | $downloadedRelease = $this->downloader->download($latestRelease); 25 | $this->storage->updateCurrentRelease($downloadedRelease); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /domains/ProjectTemplate/ProjectTemplateServiceProvider.php: -------------------------------------------------------------------------------- 1 | commands([ 19 | UpdateTemplateCommand::class, 20 | NewCommand::class, 21 | ]); 22 | 23 | $this->app->singleton( 24 | TemplateStorage::class, 25 | fn () => new TemplateStorage( 26 | Storage::disk('laravel-releases'), 27 | config('filesystems.disks.laravel-releases.root') 28 | ), 29 | ); 30 | 31 | $this->setupSchedule(); 32 | } 33 | 34 | private function setupSchedule(): void 35 | { 36 | $this->callAfterResolving(Schedule::class, function (Schedule $schedule) { 37 | $schedule 38 | ->command(UpdateTemplateCommand::class) 39 | ->hourly() 40 | ->appendOutputTo(storage_path('update-template.log')); 41 | }); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /domains/ProjectTemplate/README.md: -------------------------------------------------------------------------------- 1 | # Project Template 2 | 3 | The [laravel/laravel](https://github.com/laravel/laravel) repository is the 4 | starting point of all Laravel applications, which is why we also use it. To not 5 | need to download it on each request, we periodically check [if a new version was 6 | published](./Console/Commands/UpdateTemplateCommand.php). 7 | 8 | The downloaded archives are stored on disk. The current version is always stored 9 | in the `current/` directory and each other version is stored in a folder named 10 | after its version name on https://packagist.org. 11 | 12 | This template archive then goes through a series of tranformations depending on 13 | the values from the [Project Form](../CreateProjectForm). 14 | -------------------------------------------------------------------------------- /domains/ProjectTemplateCustomization/ProjectTemplateCustomizer.php: -------------------------------------------------------------------------------- 1 | template->currentArchive(); 25 | 26 | $this->archiveManipulatorResolver 27 | ->resolve() 28 | ->each(fn (ArchiveManipulator $am) => $am->manipulate($archive, $form)); 29 | 30 | return $archive; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /domains/ProjectTemplateCustomization/README.md: -------------------------------------------------------------------------------- 1 | # Project Template Customization 2 | 3 | After downloading the [ProjectTemplate](../ProjectTemplate), we need to adjust 4 | it based on the values from the [Project Form](../CreateProjectForm). 5 | 6 | This is primarily done by independent components, the 7 | [`ArchiveManipulator`s](../ArchiveManipulation). The 8 | [`ProjectTemplateCustomizer`](./ProjectTemplateCustomizer.php) from this package 9 | is responsible for passing the template to all 10 | [`ArchiveManipulator`s](../ArchiveManipulation/ArchiveManipulator.php) 11 | registered in the container. 12 | -------------------------------------------------------------------------------- /domains/Readme/MarkdownRenderer.php: -------------------------------------------------------------------------------- 1 | $items 58 | */ 59 | public function list(iterable $items): string 60 | { 61 | return collect($items) 62 | ->map(fn (string $item) => $this->listItem($item)) 63 | ->join(PHP_EOL); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /domains/Readme/ReadmeArchiveManipulator.php: -------------------------------------------------------------------------------- 1 | addFromString('README.md', $this->generator->render($form)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /domains/Readme/ReadmeServiceProvider.php: -------------------------------------------------------------------------------- 1 | loadViewsFrom(__DIR__.'/resources/templates', 'template'); 15 | $this->registerArchiveManipulator(ReadmeArchiveManipulator::class); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /domains/Readme/Support/Str.php: -------------------------------------------------------------------------------- 1 | explode($eol) 17 | ->map(fn (string $line) => $indent.$line) 18 | ->join($eol); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /domains/Schedule/Http/Controllers/ScheduleRunController.php: -------------------------------------------------------------------------------- 1 | Limit::perMinute(1)); 16 | 17 | Route::middleware('throttle:schedule-endpoint') 18 | ->get('/health', ScheduleRunController::class) 19 | ->name('health'); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /domains/SourceCodeManipulation/Perl/AddTrait.php: -------------------------------------------------------------------------------- 1 | 15 | */ 16 | public static function values(): array 17 | { 18 | $reflected = new ReflectionClass(self::class); 19 | $publicConstants = $reflected->getConstants(Constant::IS_PUBLIC); 20 | 21 | return $publicConstants; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /domains/Support/FileSystem/Path.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ./tests/Unit 6 | 7 | 8 | ./tests/Feature 9 | 10 | 11 | ./tests/Integration 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | ./domains 30 | 31 | 32 | 33 | ./domains/Laravel 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /public/.htaccess: -------------------------------------------------------------------------------- 1 | 2 | 3 | Options -MultiViews -Indexes 4 | 5 | 6 | RewriteEngine On 7 | 8 | # Handle Authorization Header 9 | RewriteCond %{HTTP:Authorization} . 10 | RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] 11 | 12 | # Redirect Trailing Slashes If Not A Folder... 13 | RewriteCond %{REQUEST_FILENAME} !-d 14 | RewriteCond %{REQUEST_URI} (.+)/$ 15 | RewriteRule ^ %1 [L,R=301] 16 | 17 | # Send Requests To Front Controller... 18 | RewriteCond %{REQUEST_FILENAME} !-d 19 | RewriteCond %{REQUEST_FILENAME} !-f 20 | RewriteRule ^ index.php [L] 21 | 22 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NiclasvanEyk/initializer-for-laravel/7212ac63e0c694d8218f1bc4adf28553d3eee610/public/favicon.ico -------------------------------------------------------------------------------- /public/img/og/initializer-for-laravel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NiclasvanEyk/initializer-for-laravel/7212ac63e0c694d8218f1bc4adf28553d3eee610/public/img/og/initializer-for-laravel.png -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /public/web.config: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /resources/css/app.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | -------------------------------------------------------------------------------- /resources/js/app.js: -------------------------------------------------------------------------------- 1 | import Alpine from 'alpinejs' 2 | import { share } from './shareable-url/shareable-url' 3 | 4 | window.Alpine = Alpine 5 | 6 | window.Initializer = { share } 7 | 8 | Alpine.start() 9 | -------------------------------------------------------------------------------- /resources/js/shareable-url/computeSharingUrl.js: -------------------------------------------------------------------------------- 1 | export const computeSharingUrl = ({ checkBoxes, keyValuePairs }) => { 2 | const query = [ 3 | 'preset', 4 | ...keyValuePairs.map(([key, value]) => `${key}=${value}`), 5 | ...checkBoxes.map(([key, value]) => key), 6 | ].join('&'); 7 | 8 | const { origin, pathname } = window.location 9 | 10 | return `${origin}${pathname}?${query}` 11 | } 12 | -------------------------------------------------------------------------------- /resources/js/shareable-url/extractFormValues.js: -------------------------------------------------------------------------------- 1 | import { filterEmptyValues, filterIgnoredKeys, filterStarterParameter, filterUncheckedBoxes } from './filters' 2 | 3 | export const extractFormValues = formId => { 4 | const form = document.getElementById(formId) 5 | const values = Object.fromEntries(Array.from(new FormData(form))) 6 | 7 | const checkBoxes = [] 8 | const keyValuePairs = [] 9 | 10 | for (const [key, value] of Object.entries(values)) { 11 | if (key.startsWith('uses-')) { 12 | checkBoxes.push([key, value]) 13 | } else { 14 | keyValuePairs.push([key, value]) 15 | } 16 | } 17 | 18 | return { 19 | checkBoxes: checkBoxes 20 | .filter(filterUncheckedBoxes) 21 | .filter(filterIgnoredKeys) 22 | .filter(filterEmptyValues) 23 | .filter(filterStarterParameter(keyValuePairs['starter'])), 24 | keyValuePairs: keyValuePairs 25 | .filter(filterUncheckedBoxes) 26 | .filter(filterIgnoredKeys) 27 | .filter(filterEmptyValues) 28 | .filter(filterStarterParameter(keyValuePairs['starter'])), 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /resources/js/shareable-url/filters.js: -------------------------------------------------------------------------------- 1 | const starterParameters = () => { 2 | return { 3 | 'laravel': [], 4 | 'breeze': ['breeze-frontend'], 5 | 'jetstream': ['uses-jetstream-teams', 'jetstream-frontend'], 6 | } 7 | } 8 | 9 | /** 10 | * Filters non-relevant parameters based on the starter. 11 | * 12 | * E.g. uses-jetstream-teams is not relevant when initializing a breeze project. 13 | */ 14 | export const filterStarterParameter = starter => { 15 | let irrelevant = starterParameters() 16 | delete starterParameters[starter] 17 | irrelevant = Object.entries(irrelevant).flatMap(([starter, parameters]) => parameters) 18 | 19 | return ([key, value]) => !irrelevant.includes(key) 20 | } 21 | 22 | const ignoredKeys = ['project', 'description'] 23 | export const filterIgnoredKeys = ([key, value]) => !ignoredKeys.includes(key) 24 | 25 | export const filterUncheckedBoxes = ([key, value]) => value !== 'off' 26 | export const filterEmptyValues = ([key, value]) => value !== '' 27 | && value !== undefined 28 | && !(typeof value === 'string' && value.toLocaleLowerCase() === 'none') 29 | -------------------------------------------------------------------------------- /resources/js/shareable-url/shareable-url.js: -------------------------------------------------------------------------------- 1 | import { computeSharingUrl } from './computeSharingUrl' 2 | import { extractFormValues } from './extractFormValues' 3 | 4 | export function share(formId) { 5 | const url = computeSharingUrl(extractFormValues(formId)) 6 | 7 | if ('share' in navigator) { 8 | navigator.share({url}) 9 | } else { 10 | window.location = url; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /resources/lang/en/auth.php: -------------------------------------------------------------------------------- 1 | 'These credentials do not match our records.', 17 | 'password' => 'The provided password is incorrect.', 18 | 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.', 19 | 20 | ]; 21 | -------------------------------------------------------------------------------- /resources/lang/en/pagination.php: -------------------------------------------------------------------------------- 1 | '« Previous', 17 | 'next' => 'Next »', 18 | 19 | ]; 20 | -------------------------------------------------------------------------------- /resources/lang/en/passwords.php: -------------------------------------------------------------------------------- 1 | 'Your password has been reset!', 17 | 'sent' => 'We have emailed your password reset link!', 18 | 'throttled' => 'Please wait before retrying.', 19 | 'token' => 'This password reset token is invalid.', 20 | 'user' => "We can't find a user with that email address.", 21 | 22 | ]; 23 | -------------------------------------------------------------------------------- /resources/views/components/button/big.blade.php: -------------------------------------------------------------------------------- 1 | @props(['secondary' => false]) 2 | 3 | -------------------------------------------------------------------------------- /resources/views/components/first-party-package/choice.blade.php: -------------------------------------------------------------------------------- 1 | @props([ 2 | 'heading', 3 | 'options', 4 | 'model', 5 | 'default' => 'none', 6 | 'href' => null, 7 | ]) 8 | 9 | @php 10 | /** @var \Domains\Laravel\ComposerPackages\FirstPartyPackage[] $options */ 11 | @endphp 12 | 13 | 18 | @if($default === 'none') 19 | 20 | @endif 21 | @foreach($options as $package) 22 | @php $packageId = $package->id(); @endphp 23 | 30 | {{ $package->description() }} 31 | 32 | @endforeach 33 | 34 | -------------------------------------------------------------------------------- /resources/views/components/first-party-package/option-group.blade.php: -------------------------------------------------------------------------------- 1 | @props(['heading', 'packages', 'href' => null]) 2 | 3 | @php 4 | /** @var \Domains\Laravel\ComposerPackages\FirstPartyPackage[] $packages */ 5 | @endphp 6 | 7 | 8 | @foreach($packages as $package) 9 | 10 | @endforeach 11 | 12 | -------------------------------------------------------------------------------- /resources/views/components/first-party-package/option.blade.php: -------------------------------------------------------------------------------- 1 | @props([ 2 | 'id', 3 | 'package', 4 | 'tags' => null, 5 | ]) 6 | 7 | @php /** @var \Domains\Composer\ComposerDependency $package */ @endphp 8 | 9 | merge([ 'id' => $id ]) }} 11 | :heading="$package->name()" 12 | :href="$package->href()" 13 | > 14 | {!! $package->description() !!} 15 | 16 | 17 | {{ $tags }} 18 | 19 | -------------------------------------------------------------------------------- /resources/views/components/form-control/checkbox.blade.php: -------------------------------------------------------------------------------- 1 | @props([ 2 | 'id', 3 | 'heading', 4 | 'name' => null, 5 | 'href' => null, 6 | 'tags' => null, 7 | 'checked' => false, 8 | 'readonly' => false, 9 | ]) 10 | 11 | @php 12 | $name ??= $id; 13 | @endphp 14 | 15 | 23 | 24 | 33 | 34 | 35 | {{ $slot }} 36 | 37 | 38 | {{ $tags }} 39 | 40 | 41 | -------------------------------------------------------------------------------- /resources/views/components/form-control/group.blade.php: -------------------------------------------------------------------------------- 1 | @props(['heading', 'href' => null]) 2 | 3 |
7 | 8 | 9 | {{ $heading }} 10 | 11 | 12 | @if($href !== null) 13 | 16 | 17 | 18 | 19 | Documentation 20 | 21 | @endif 22 | 23 | 24 |
25 | {{ $slot }} 26 |
27 |
28 | -------------------------------------------------------------------------------- /resources/views/components/form-control/radio.blade.php: -------------------------------------------------------------------------------- 1 | @props([ 2 | 'id', 3 | 'heading', 4 | 'name' => null, 5 | 'href' => null, 6 | 'tags' => null, 7 | 'checked' => false, 8 | 'readonly' => false, 9 | ]) 10 | 11 | @php 12 | $name ??= $id; 13 | @endphp 14 | 15 | 23 | 24 | 33 | 34 | 35 | {{ $slot }} 36 | 37 | 38 | {{ $tags }} 39 | 40 | 41 | -------------------------------------------------------------------------------- /resources/views/components/form-section.blade.php: -------------------------------------------------------------------------------- 1 | @props(['name', 'description', 'icon']) 2 | 3 | @php 4 | $id = \Illuminate\Support\Str::slug($name) 5 | @endphp 6 | 7 |
8 |
9 |

14 | {{ $icon }} {{ $name }} 15 |

16 | 17 |
18 | {{ $description }} 19 |
20 |
21 | 22 |
23 | {{$slot}} 24 |
25 |
-------------------------------------------------------------------------------- /resources/views/components/head/opengraph-tags.blade.php: -------------------------------------------------------------------------------- 1 | @props(['url', 'image', 'title', 'description']) 2 | 3 | @php 4 | $host = parse_url($url)['host']; 5 | @endphp 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /resources/views/components/icons/beaker.blade.php: -------------------------------------------------------------------------------- 1 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /resources/views/components/icons/bell.blade.php: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /resources/views/components/icons/bolt.blade.php: -------------------------------------------------------------------------------- 1 | 7 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /resources/views/components/icons/code.blade.php: -------------------------------------------------------------------------------- 1 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /resources/views/components/icons/credit-card.blade.php: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /resources/views/components/icons/database.blade.php: -------------------------------------------------------------------------------- 1 | 7 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /resources/views/components/icons/dots.blade.php: -------------------------------------------------------------------------------- 1 | 8 | 9 | 10 | 11 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /resources/views/components/icons/download.blade.php: -------------------------------------------------------------------------------- 1 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /resources/views/components/icons/home.blade.php: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /resources/views/components/icons/info.blade.php: -------------------------------------------------------------------------------- 1 | 4 | 5 | 9 | 10 | -------------------------------------------------------------------------------- /resources/views/components/icons/lock.blade.php: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /resources/views/components/icons/mail.blade.php: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /resources/views/components/icons/megaphone.blade.php: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 19 | -------------------------------------------------------------------------------- /resources/views/components/icons/search.blade.php: -------------------------------------------------------------------------------- 1 | 7 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /resources/views/components/icons/storage.blade.php: -------------------------------------------------------------------------------- 1 | 7 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /resources/views/components/icons/template.blade.php: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /resources/views/components/inline-radio.blade.php: -------------------------------------------------------------------------------- 1 | @props([ 2 | 'id', 3 | 'value', 4 | 'name', 5 | 'checked' => false, 6 | 'colored', 7 | 'color', 8 | ]) 9 | 10 | @php 11 | $color ??= 'red'; 12 | $focusRing = match($color) { 13 | 'yellow' => 'focus:ring-yellow-500', 14 | 'indigo' => 'focus:ring-indigo-500', 15 | default => 'focus:ring-$red-500' 16 | }; 17 | 18 | $textColor = match($color) { 19 | 'yellow' => 'text-yellow-600', 20 | 'indigo' => 'text-indigo-600', 21 | default => 'text-red-600' 22 | }; 23 | @endphp 24 | 25 | -------------------------------------------------------------------------------- /resources/views/components/layout/default.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 14 | 15 | {{ config('app.name') }} 16 | 17 | {{-- https://css-tricks.com/emojis-as-favicons --}} 18 | 19 | 20 | 21 | @googlefonts 22 | 23 | @vite(['resources/css/app.css', 'resources/js/app.js']) 24 | 29 | 30 | 31 |
33 |
34 | 35 | 36 | {{ $slot }} 37 |
38 |
39 | 40 | -------------------------------------------------------------------------------- /resources/views/components/link.blade.php: -------------------------------------------------------------------------------- 1 | @props(['href']) 2 | @php 3 | /** @var string $href */ 4 | 5 | $internal = parse_url($href)['host'] === parse_url(config('app.url'))['host']; 6 | @endphp 7 | merge([ 8 | 'class' => 'font-medium text-red-600 dark:text-red-500 hover:text-red-500 dark:hover:text-red-600 hover:underline', 9 | ]) }} @if(!$internal) target="_blank" rel="noopener" @endif href="{{$href}}">{{$slot}} -------------------------------------------------------------------------------- /resources/views/components/nav/link.blade.php: -------------------------------------------------------------------------------- 1 | @props(['route']) 2 | 3 | 10 | {{ $slot }} 11 | 12 | -------------------------------------------------------------------------------- /resources/views/components/optional.blade.php: -------------------------------------------------------------------------------- 1 | merge(['class' => 'text-gray-500'])}}>(optional) 2 | -------------------------------------------------------------------------------- /resources/views/components/radio-option-none.blade.php: -------------------------------------------------------------------------------- 1 | @props(['id', 'model', 'inline' => false, 'name' => null, 'label' => 'None']) 2 | 3 | 12 | -------------------------------------------------------------------------------- /resources/views/components/sail/choice.blade.php: -------------------------------------------------------------------------------- 1 | @props([ 2 | 'heading', 3 | 'options', 4 | 'model', 5 | 'default' => 'none', 6 | 'href' => null, 7 | 'inline' => false, 8 | 'optional' => false, 9 | ]) 10 | 11 | @php 12 | /** @var \Domains\Laravel\Sail\SailConfigurationOption[] $options */ 13 | /** @var string $model */ 14 | 15 | // If we use a $model containing a "-", alpine will throw up if we use it 16 | // directly. So if it contains a dash, we'll change the alpine model to 17 | // CamelCase, but still use the original $model as the name, so the result 18 | // in the form won't be altered 19 | $name = substr($model, 0); 20 | $model = \Illuminate\Support\Str::contains($model, '-') 21 | ? \Illuminate\Support\Str::studly($model) 22 | : $model; 23 | @endphp 24 | 25 | 30 | @if($default === 'none' || $optional) 31 | 32 | @endif 33 | 34 | @foreach($options as $option) 35 | 43 | {{ $option->description() }} 44 | 45 | @endforeach 46 | 47 | -------------------------------------------------------------------------------- /resources/views/components/sail/option.blade.php: -------------------------------------------------------------------------------- 1 | @props(['id', 'option']) 2 | @php 3 | use Domains\CreateProjectForm\Http\Request\CreateProjectRequest\CreateProjectRequestParameter as P; 4 | /** @var \Domains\Composer\ComposerDependency $option */ 5 | 6 | $id = $option->id(); 7 | @endphp 8 | 9 | 15 | {!! $option->description() !!} 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /resources/views/components/sponsor-button.blade.php: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /resources/views/components/tag.blade.php: -------------------------------------------------------------------------------- 1 | merge([ 2 | 'class' => 'px-3 inline-flex text-sm leading-6 font-semibold rounded-full' 3 | ]) }}> 4 | {{ $slot }} 5 | 6 | -------------------------------------------------------------------------------- /resources/views/components/tags/community.blade.php: -------------------------------------------------------------------------------- 1 | 10 | Community 11 | 12 | -------------------------------------------------------------------------------- /resources/views/components/tags/sail.blade.php: -------------------------------------------------------------------------------- 1 | @props(['tooltip' => true]) 2 | 3 | @php 4 | $classes = "bg-indigo-100 hover:bg-indigo-300 5 | dark:bg-indigo-800 dark:bg-opacity-70 dark:hover:bg-indigo-600 6 | text-indigo-800 dark:text-indigo-100 7 | transition"; 8 | 9 | if ($tooltip) { 10 | $classes .= "cursor-help"; 11 | } 12 | 13 | $title = $tooltip 14 | ? "This option includes a Laravel Sail service, so you can develop locally using nearly the same infrastructure as in your production environment." 15 | : ''; 16 | @endphp 17 | 18 | 22 | Sail 23 | -------------------------------------------------------------------------------- /resources/views/components/validation/errors.blade.php: -------------------------------------------------------------------------------- 1 | @props(['errors']) 2 | 3 | @php /** @var \Illuminate\Support\ViewErrorBag $errors */ @endphp 4 | 5 | @if ($errors->any()) 6 | 17 | @endif 18 | -------------------------------------------------------------------------------- /resources/views/partials/form-section/notifications.blade.php: -------------------------------------------------------------------------------- 1 | @php 2 | 3 | @endphp 4 | 5 | 6 | 7 |

8 | Notifications are everywhere and Laravel supports multiple ways of 9 | sending those to you users. You can store them in the database, 10 |

11 |
12 | 13 | 14 | 15 | 16 | 17 | 21 | {{-- --}} 28 | {{-- {{ $mailgun->description() }}--}} 29 | {{-- --}} 30 | 31 | {{-- --}} 38 | {{-- {{ $postmark->description() }}--}} 39 | {{-- --}} 40 | 41 |
-------------------------------------------------------------------------------- /resources/views/partials/form-section/starter-kit.blade.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | Laravel provides a few 4 | 5 | starter kits 6 | for your application, which provide various authentication 7 | features out of the box. 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /storage/app/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/debugbar/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/.gitignore: -------------------------------------------------------------------------------- 1 | compiled.php 2 | config.php 3 | down 4 | events.scanned.php 5 | maintenance.php 6 | routes.php 7 | routes.scanned.php 8 | schedule-* 9 | services.json 10 | -------------------------------------------------------------------------------- /storage/framework/cache/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !data/ 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /storage/framework/cache/data/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/sessions/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/testing/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/framework/views/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /storage/logs/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | import colors from "tailwindcss/colors"; 2 | import defaultTheme from "tailwindcss/defaultTheme"; 3 | import forms from "@tailwindcss/forms"; 4 | import typography from "@tailwindcss/typography"; 5 | 6 | module.exports = { 7 | mode: "jit", 8 | content: ["./resources/**/*.{blade.php,js,vue}", "./domains/**/*.php"], 9 | theme: { 10 | extend: { 11 | colors: { 12 | ...defaultTheme.colors, 13 | gray: { 14 | ...colors.gray, 15 | // Less blue-ish colors for dark mode 16 | 800: "rgba(23,25,35)", 17 | 900: "#12141c", 18 | }, 19 | }, 20 | fontFamily: { 21 | sans: ["Inter", ...defaultTheme.fontFamily.sans], 22 | }, 23 | }, 24 | }, 25 | plugins: [forms, typography], 26 | }; 27 | -------------------------------------------------------------------------------- /tests/CreatesApplication.php: -------------------------------------------------------------------------------- 1 | make(Kernel::class)->bootstrap(); 20 | 21 | return $app; 22 | } 23 | 24 | public static function createStaticApplication(): Application 25 | { 26 | $app = require __DIR__.'/../bootstrap/app.php'; 27 | 28 | $app->make(Kernel::class)->bootstrap(); 29 | 30 | return $app; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /tests/Feature/Domains/Composer/ComposerJsonFixtures.php: -------------------------------------------------------------------------------- 1 | app->make(PackagistApiClient::class); 19 | $results = $client->packageReleases('laravel', 'laravel'); 20 | 21 | $this->assertTrue(count($results) > 100); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/Feature/Domains/ProjectCreation/ArchiveManipulation/InstallScriptGeneratorTest.php: -------------------------------------------------------------------------------- 1 | generator = $this->app->make(InitializationScriptGenerator::class); 18 | } 19 | 20 | /** @test */ 21 | public function it_contains_project_setup_instructions(): void 22 | { 23 | $result = $this->generator->render( 24 | CreateProjectFormFixtures::allOptionsEnabled(), 25 | ); 26 | 27 | $this->assertStringContainsString('passport:install', $result); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/Feature/Domains/ProjectTemplate/Laravel862Package.php: -------------------------------------------------------------------------------- 1 | resolver()->resolve(); 18 | 19 | $manipulators->each(function ($manipulator) { 20 | $this->assertInstanceOf(ArchiveManipulator::class, $manipulator); 21 | }); 22 | $this->assertCount(4, $manipulators); 23 | } 24 | 25 | private function resolver(): ArchiveManipulatorResolver 26 | { 27 | return $this->app->make(ArchiveManipulatorResolver::class); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /tests/Feature/Domains/Support/PathTest.php: -------------------------------------------------------------------------------- 1 | assertEquals(Path::join('foo', 'bar'), 'foo/bar'); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/TestCase.php: -------------------------------------------------------------------------------- 1 |