Skip to content

Commit f16a65b

Browse files
Initial release
1 parent 059a4f9 commit f16a65b

50 files changed

Lines changed: 4486 additions & 1 deletion

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.editorconfig

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
root = true
2+
3+
[*]
4+
charset = utf-8
5+
end_of_line = lf
6+
indent_size = 4
7+
indent_style = space
8+
insert_final_newline = true
9+
trim_trailing_whitespace = true
10+
11+
[*.{yml,yaml,json}]
12+
indent_size = 2
13+
14+
[*.md]
15+
trim_trailing_whitespace = false

.gitattributes

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/.github export-ignore
2+
/tests export-ignore
3+
/.gitattributes export-ignore
4+
/.gitignore export-ignore
5+
/phpunit.xml.dist export-ignore
6+
/.editorconfig export-ignore
7+
8+
*.md diff=markdown
9+
*.php diff=php

.github/workflows/tests.yml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: tests
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
13+
strategy:
14+
fail-fast: false
15+
matrix:
16+
php: ['8.1', '8.2', '8.3', '8.4']
17+
laravel: ['10.*', '11.*', '12.*']
18+
exclude:
19+
- php: '8.1'
20+
laravel: '11.*'
21+
- php: '8.1'
22+
laravel: '12.*'
23+
24+
name: PHP ${{ matrix.php }} / Laravel ${{ matrix.laravel }}
25+
26+
steps:
27+
- uses: actions/checkout@v4
28+
29+
- name: Setup PHP
30+
uses: shivammathur/setup-php@v2
31+
with:
32+
php-version: ${{ matrix.php }}
33+
extensions: bcmath, ctype, curl, dom, fileinfo, json, mbstring, openssl, pdo, pdo_sqlite, tokenizer, xml
34+
coverage: none
35+
36+
- name: Cache Composer dependencies
37+
uses: actions/cache@v4
38+
with:
39+
path: ~/.composer/cache
40+
key: composer-${{ runner.os }}-${{ matrix.php }}-${{ matrix.laravel }}-${{ hashFiles('composer.json') }}
41+
42+
- name: Install dependencies
43+
run: |
44+
composer require "illuminate/contracts:${{ matrix.laravel }}" --no-update
45+
composer update --prefer-dist --no-interaction --no-progress
46+
47+
- name: Run tests
48+
run: vendor/bin/phpunit

.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/vendor
2+
/node_modules
3+
composer.lock
4+
.phpunit.cache
5+
.phpunit.result.cache
6+
.DS_Store
7+
.idea
8+
.vscode
9+
*.log

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2026 NativeCode
3+
Copyright (c) 2026 NativeCode (https://nativecode.in)
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 284 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,284 @@
1+
<h1 align="center">laravel-install-wizard</h1>
2+
3+
<p align="center">
4+
A minimal, modern, multilingual Laravel installation wizard.<br />
5+
shadcn-style UI · light / dark / system theme · 10 languages · zero CDN runtime deps.
6+
</p>
7+
8+
<p align="center">
9+
<a href="https://packagist.org/packages/nativecodein/laravel-install-wizard"><img src="https://img.shields.io/packagist/v/nativecodein/laravel-install-wizard.svg?style=flat-square" alt="Latest Version on Packagist" /></a>
10+
<a href="https://packagist.org/packages/nativecodein/laravel-install-wizard"><img src="https://img.shields.io/packagist/dt/nativecodein/laravel-install-wizard.svg?style=flat-square" alt="Total Downloads" /></a>
11+
<a href="https://packagist.org/packages/nativecodein/laravel-install-wizard"><img src="https://img.shields.io/packagist/php-v/nativecodein/laravel-install-wizard.svg?style=flat-square" alt="PHP Version" /></a>
12+
<a href="https://github.com/nativecodein/laravel-install-wizard/actions"><img src="https://img.shields.io/github/actions/workflow/status/nativecodein/laravel-install-wizard/tests.yml?branch=main&style=flat-square&label=tests" alt="Tests" /></a>
13+
<a href="LICENSE"><img src="https://img.shields.io/packagist/l/nativecodein/laravel-install-wizard.svg?style=flat-square" alt="License" /></a>
14+
</p>
15+
16+
---
17+
18+
When a fresh Laravel app has not yet been installed, `laravel-install-wizard` gently redirects every route to a clean web-based installer. The user names the app, configures the environment and database, sees PHP requirement and folder permission checks, then clicks **Install**. A `.installed` lock file is written and the wizard never appears again.
19+
20+
## Table of contents
21+
22+
- [Highlights](#highlights)
23+
- [Screenshots](#screenshots)
24+
- [Requirements](#requirements)
25+
- [Installation](#installation)
26+
- [Quick start](#quick-start)
27+
- [Configuration](#configuration)
28+
- [Multilingual support](#multilingual-support)
29+
- [Theming](#theming)
30+
- [Customizing views and assets](#customizing-views-and-assets)
31+
- [Resetting installation](#resetting-installation)
32+
- [Security](#security)
33+
- [Testing](#testing)
34+
- [Contributing](#contributing)
35+
- [Versioning](#versioning)
36+
- [Credits](#credits)
37+
- [License](#license)
38+
39+
## Highlights
40+
41+
- **Multi-step wizard** — Welcome → Environment → Database → Requirements → Permissions → Install
42+
- **Dynamic branding** — enter `NativeCode` and the installer becomes the *NativeCode Installer* everywhere
43+
- **Live database test** — MySQL, PostgreSQL, SQLite, SQL Server, validated before continuing
44+
- **Safe `.env` writer** — preserves comments, leaves unrelated keys alone, validates key format
45+
- **10 languages out of the box** — English, Spanish, French, German, Portuguese, Italian, Japanese, Chinese, Arabic (RTL), Hindi
46+
- **Light / Dark / System theme**`localStorage` persistence, OS-preference reactive, no FOUC
47+
- **shadcn-style UI** — HSL CSS variables, Outfit font, accessible menus, keyboard nav
48+
- **Zero CDN runtime deps** — all CSS, JS and confetti inlined; only Google Fonts for Outfit
49+
- **Production-ready** — works without JavaScript via progressive enhancement
50+
- **Auto-discovered** — drop in via Composer, no service-provider wiring required
51+
52+
## Screenshots
53+
54+
> Add screenshots here once the package is hosted. Suggested shots:
55+
> `docs/welcome-light.png`, `docs/database-dark.png`, `docs/complete-rtl.png`.
56+
57+
```
58+
[ welcome — light ] [ database — dark ] [ complete — confetti ]
59+
```
60+
61+
## Requirements
62+
63+
- PHP 8.1, 8.2, 8.3 or 8.4
64+
- Laravel 10, 11 or 12
65+
66+
## Installation
67+
68+
```bash
69+
composer require nativecodein/laravel-install-wizard
70+
```
71+
72+
The service provider is auto-registered. On first request, since `storage/.installed` doesn't exist yet, every route redirects to `/install`.
73+
74+
### Publishing files (optional)
75+
76+
```bash
77+
# everything
78+
php artisan vendor:publish --tag=installwizard
79+
80+
# or individually
81+
php artisan vendor:publish --tag=installwizard-config
82+
php artisan vendor:publish --tag=installwizard-views
83+
php artisan vendor:publish --tag=installwizard-lang
84+
php artisan vendor:publish --tag=installwizard-assets
85+
```
86+
87+
## Quick start
88+
89+
1. Install via Composer.
90+
2. Open any route in your Laravel app — you'll be redirected to `/install`.
91+
3. Enter your application name (e.g. `NativeCode`).
92+
4. Fill in environment, database, watch the requirement and permission checks pass.
93+
5. Click **Install NativeCode**. The package writes `.env`, generates `APP_KEY`, clears caches, creates `storage/.installed`.
94+
6. Confetti fires. You're sent back to the route you originally requested.
95+
7. Future visits never see the wizard again.
96+
97+
## Configuration
98+
99+
After publishing the config, all behavior lives in `config/installwizard.php`:
100+
101+
| Key | Default | Description |
102+
|---|---|---|
103+
| `installed_file` | `storage_path('.installed')` | Lock file that gates the wizard |
104+
| `route_prefix` | `install` | URL prefix for wizard routes |
105+
| `auto_apply_middleware` | `true` | Append the gating middleware to the `web` group automatically |
106+
| `redirect_after_install` | `/` | Fallback target after install if no intended URL |
107+
| `required_extensions` | 12 standard exts | PHP extensions checked in step 4 |
108+
| `writable_paths` | storage + bootstrap/cache | Paths verified in step 5 |
109+
| `final.run_migrations` | `false` | Run `migrate --force` at the end |
110+
| `final.run_seeders` | `false` | Run `db:seed --force` at the end |
111+
| `final.generate_key` | `true` | Generate `APP_KEY` if missing |
112+
| `final.clear_caches` | `true` | Clear config/route/view/cache stores |
113+
| `locales` | 10 locales | Languages offered in the switcher |
114+
| `rtl_locales` | `['ar','he','fa','ur']` | Forced right-to-left layout |
115+
| `default_theme` | `system` | Initial theme: `light`, `dark`, or `system` |
116+
117+
## Multilingual support
118+
119+
Ten locales ship out of the box. A globe button in the header opens a language picker; the choice persists in the user's session.
120+
121+
| Code | Language | Code | Language |
122+
|---|---|---|---|
123+
| `en` | English | `it` | Italiano |
124+
| `es` | Español | `ja` | 日本語 |
125+
| `fr` | Français | `zh` | 中文 |
126+
| `de` | Deutsch | `ar` | العربية (RTL) |
127+
| `pt` | Português | `hi` | हिन्दी |
128+
129+
### Adding a language
130+
131+
```bash
132+
php artisan vendor:publish --tag=installwizard-lang
133+
```
134+
135+
Create `lang/vendor/installwizard/{locale}/messages.php`, copy keys from `en/messages.php`, translate, then declare it in config:
136+
137+
```php
138+
// config/installwizard.php
139+
'locales' => [
140+
'en' => 'English',
141+
'tr' => 'Türkçe', // new
142+
],
143+
'rtl_locales' => ['ar', 'he', 'fa', 'ur'], // add new RTL locales here
144+
```
145+
146+
RTL locales render with `dir="rtl"` automatically.
147+
148+
## Theming
149+
150+
The theme toggle in the header offers three modes:
151+
152+
- **Light**`<html>` has no `dark` class
153+
- **Dark**`<html class="dark">`
154+
- **System** — follows `prefers-color-scheme` and reacts live to OS changes
155+
156+
The choice is stored in `localStorage` under `installwizard.theme`. An inline `<script>` in `<head>` applies the class before paint, so there is no flash.
157+
158+
### Customizing colors
159+
160+
Publish the views, then edit the CSS variables at the top of `resources/views/vendor/installwizard/layout.blade.php`:
161+
162+
```css
163+
:root {
164+
--primary: 240 5.9% 10%;
165+
--background: 0 0% 100%;
166+
/**/
167+
}
168+
.dark {
169+
--primary: 0 0% 98%;
170+
/**/
171+
}
172+
```
173+
174+
All variables follow [shadcn/ui](https://ui.shadcn.com) conventions — HSL component triplets consumed with `hsl(var(--token))`.
175+
176+
## Customizing views and assets
177+
178+
```bash
179+
php artisan vendor:publish --tag=installwizard-views
180+
```
181+
182+
Views land in `resources/views/vendor/installwizard/` and override the package versions automatically. Edit them however you like — the package will pick up your changes immediately.
183+
184+
Assets are inlined into the layout by default, so publishing CSS/JS is only needed if you want to bundle the wizard into your own Vite pipeline.
185+
186+
## Resetting installation
187+
188+
```bash
189+
# wipe the lock file — wizard appears on the next request
190+
rm storage/.installed
191+
```
192+
193+
Or programmatically:
194+
195+
```php
196+
app(\Nativecodein\LaravelInstallWizard\Services\Installer::class)->removeLockFile();
197+
```
198+
199+
## Security
200+
201+
- The `EnvWriter` validates env keys against `/^[A-Z_][A-Z0-9_]*$/` and rejects anything else.
202+
- Existing comments and unrelated `.env` values are preserved during writes.
203+
- All forms are CSRF-protected through the `web` middleware group.
204+
- The locale switcher validates against the configured allow-list before persisting.
205+
- The gating middleware only stores intended URLs for GET requests (never AJAX/XHR), preventing redirect loops.
206+
- API requests get a 503 JSON response instead of a redirect, preventing fetch/axios redirect loops.
207+
- No external CDN dependencies at runtime — all CSS, JS and confetti are inlined.
208+
209+
If you discover a security vulnerability, please email **security@nativecode.in** rather than opening a public issue.
210+
211+
## Testing
212+
213+
```bash
214+
composer install
215+
vendor/bin/phpunit
216+
```
217+
218+
The suite uses [Orchestra Testbench](https://github.com/orchestral/testbench) and covers:
219+
220+
- redirects when not installed / access granted when installed
221+
- creation of the `.installed` lock file
222+
- safe `.env` writing (comment & key preservation)
223+
- database tester (success & failure paths)
224+
- requirement checker (extensions, writable paths)
225+
- middleware redirect-loop avoidance
226+
- locale persistence, RTL detection, per-locale translation rendering
227+
228+
## Contributing
229+
230+
Contributions are welcome. To get started:
231+
232+
```bash
233+
git clone https://github.com/nativecodein/laravel-install-wizard.git
234+
cd laravel-install-wizard
235+
composer install
236+
vendor/bin/phpunit
237+
```
238+
239+
### Submitting changes
240+
241+
1. Fork the repo and create a feature branch: `git checkout -b feature/your-thing`
242+
2. Write or update tests for your change.
243+
3. Ensure `vendor/bin/phpunit` passes locally.
244+
4. Open a pull request describing the *why* (motivation) and the *what* (change summary).
245+
246+
### Reporting issues
247+
248+
When opening a bug report, please include:
249+
250+
- Laravel and PHP versions (`php artisan --version`, `php -v`)
251+
- The contents of `config/installwizard.php` if you've customized it
252+
- Browser and OS for UI bugs
253+
- A minimal reproduction repo if possible
254+
255+
### Translations
256+
257+
To contribute a new language, copy `src/resources/lang/en/messages.php`, translate, and submit a PR. Native speakers reviewing existing translations are also very welcome.
258+
259+
### Code style
260+
261+
This project follows PSR-12. Keep controllers thin, services pure, and Blade views accessible. Avoid introducing runtime CDN dependencies — everything that ships in the layout is inlined deliberately.
262+
263+
## Versioning
264+
265+
This package follows [Semantic Versioning](https://semver.org). Breaking changes only ship in major releases.
266+
267+
## Credits
268+
269+
- [NativeCode](https://nativecode.in) — original author and maintainer
270+
- [Laravel](https://laravel.com) — the framework this package extends
271+
- [shadcn/ui](https://ui.shadcn.com) — design tokens and component vocabulary that inspired the UI
272+
- [Outfit](https://fonts.google.com/specimen/Outfit) — typeface
273+
- All [contributors](https://github.com/nativecodein/laravel-install-wizard/contributors)
274+
275+
## License
276+
277+
The MIT License (MIT). Please see the [LICENSE](LICENSE) file for more information.
278+
279+
---
280+
281+
<p align="center">
282+
Contributed by <a href="https://nativecode.in"><strong>NativeCode</strong></a><br />
283+
<a href="https://nativecode.in">https://nativecode.in</a>
284+
</p>

0 commit comments

Comments
 (0)