You've already forked php-flasher
mirror of
https://github.com/php-flasher/php-flasher.git
synced 2026-04-05 12:32:55 +01:00
Compare commits
476 Commits
v2.0.1
...
fd65254d63
| Author | SHA1 | Date | |
|---|---|---|---|
| fd65254d63 | |||
| 33ac9013d5 | |||
| 1cc6a7c537 | |||
| dfe9a12fe1 | |||
| 8074bb1f90 | |||
| 03942aa634 | |||
| 6abae0bdde | |||
| 05c15399ac | |||
| 1bd85021d9 | |||
| 359e6de361 | |||
| e417105f7a | |||
| abd70c1d4b | |||
| 9acddbda52 | |||
| 7d6e9b46b8 | |||
| f1051e1d7f | |||
| 87da42fdea | |||
| 4d9cda22cf | |||
| c58f3c7b40 | |||
| 47eb66e874 | |||
| 30de24f054 | |||
| 162ea87330 | |||
| 8cda9d1eb1 | |||
| 6d314dbc07 | |||
| ad5c0f56dd | |||
| fd36c2ec0c | |||
| 5202c86107 | |||
| 9e7bb17faa | |||
| 83dc9e49dc | |||
| 1d81de581b | |||
| 2ebdbecda6 | |||
| 851e0a00ed | |||
| d9b0b6998e | |||
| ed992d78f6 | |||
| 0612a3bb61 | |||
| c9a61ba69c | |||
| f9746f607b | |||
| 18c2233baa | |||
| 08c242b45a | |||
| cd53ceb139 | |||
| 549c36eeee | |||
| ea0dccc961 | |||
| d33de77835 | |||
| 62848e0fd1 | |||
| c5059adac7 | |||
| 4145b870dd | |||
| 18a31f578b | |||
| f20bdebda0 | |||
| f9807e91e2 | |||
| e35339dca9 | |||
| f9bef40ae6 | |||
| 670e40dc97 | |||
| 2b0e736d28 | |||
| b79902779e | |||
| 8779de6c62 | |||
| c074feea05 | |||
| 033d650497 | |||
| 913f7b9d17 | |||
| 9eb6dcf8fa | |||
| 06f75b21eb | |||
| 0fe2e3e38e | |||
| 3ee5ba2909 | |||
| ca1a38d282 | |||
| 917b2c8f06 | |||
| 80cf92af09 | |||
| 82d0bc5a26 | |||
| 32055b1e87 | |||
| 9c07b5a72e | |||
| fdfd8e0b50 | |||
| 18712ba51e | |||
| abc8cf2569 | |||
| e1e3f01dce | |||
| 5aa8500683 | |||
| cea67fe813 | |||
| 3a47e100a0 | |||
| 93c5e987fc | |||
| 151c4f7778 | |||
| a5849a615b | |||
| 1801e187ac | |||
| 6eede92db6 | |||
| 0e04125627 | |||
| aeca5b5ee7 | |||
| 1b2f45f964 | |||
| e70d40ef04 | |||
| 0b9cfe80d5 | |||
| 767939a38c | |||
| d7234c64a2 | |||
| 194eab473e | |||
| 521746f813 | |||
| 34d780b0b7 | |||
| 61f991f379 | |||
| cc9fa57c4a | |||
| 613c73d7b6 | |||
| 9239063159 | |||
| 2e61a0539f | |||
| 548044bd7f | |||
| 3f920f2c01 | |||
| 65e9125539 | |||
| a0873c0082 | |||
| 1c5b533126 | |||
| f78824b8d9 | |||
| e212c0157e | |||
| fcf5c63f58 | |||
| ea164fde17 | |||
| 611fda9c61 | |||
| 21348f384d | |||
| 8f594698c7 | |||
| d65300a0e9 | |||
| a002590d56 | |||
| 5a4d46b46b | |||
| 0232edc9bd | |||
| 1c5fbbba9a | |||
| 15da40c582 | |||
| 8c77e96eb6 | |||
| 91ab4fa0f4 | |||
| b08117853a | |||
| 2417333107 | |||
| 358ad11c4d | |||
| a7823205ce | |||
| 50d6acfa94 | |||
| dd3c9f74f0 | |||
| fac5ca638a | |||
| 09199d8b56 | |||
| d9c65d274b | |||
| bde270a483 | |||
| c454fbc768 | |||
| 17a0e756d9 | |||
| 5ee7d58d7c | |||
| e0b93784bd | |||
| 18663b3214 | |||
| 7cf3de856e | |||
| e0cbc53c76 | |||
| b5bf2325be | |||
| e3158290f3 | |||
| 4070978256 | |||
| d96a953488 | |||
| ea8391eb6b | |||
| 3fc0d83dd6 | |||
| 1cb12c819b | |||
| f9d79f4589 | |||
| a3ce6a5262 | |||
| ff2cc1dc65 | |||
| 2cef5b98b2 | |||
| d7ecfb69a9 | |||
| 4909da7ba8 | |||
| f854ed4315 | |||
| 424617103f | |||
| 8dd56001db | |||
| e1ae7e215c | |||
| 730c13c447 | |||
| 12b0842cdd | |||
| 93ca18a67b | |||
| 1022991877 | |||
| 4345f2aa91 | |||
| 56dd1cea4c | |||
| 315a54eb43 | |||
| 82f2c69d65 | |||
| 91993e438b | |||
| 977c645c45 | |||
| 7a083efea0 | |||
| 5448e54f77 | |||
| c92105377d | |||
| 5cf68f2e34 | |||
| 68d7bfadce | |||
| ca6e75ba9d | |||
| 3407e309da | |||
| dce23cc288 | |||
| c1cc26379d | |||
| cc0658b3fe | |||
| a2abd9455a | |||
| 8d160a6659 | |||
| 8e6f0e8c88 | |||
| 4471ae6135 | |||
| 6d162c7f95 | |||
| 4f8e179fb8 | |||
| 53d7795292 | |||
| eec4b88872 | |||
| 37ac39e2ec | |||
| ef05362467 | |||
| 05229b0b42 | |||
| 28ca9d1370 | |||
| 03c358ce44 | |||
| 0edf9cc711 | |||
| 04685fad82 | |||
| 2bfc7ec5d4 | |||
| 4ef7a12484 | |||
| 4f09f06e07 | |||
| 00c8273272 | |||
| 2a7657b09c | |||
| 24d3c90752 | |||
| 5f4a8beaa3 | |||
| 70e08fc913 | |||
| f0a11e6600 | |||
| 66704f6368 | |||
| c18fbd1124 | |||
| 1899de104f | |||
| cd3ef599e1 | |||
| eb537353c2 | |||
| 4b1b747abe | |||
| 56109d9ed0 | |||
| a80c04bb19 | |||
| cd2c28ff11 | |||
| 3c79064e8d | |||
| 1e87cf5380 | |||
| 6dbef1d819 | |||
| c03c28533b | |||
| 59a2e502c8 | |||
| 3cb6ea7ed7 | |||
| bb83f55711 | |||
| ffbb8e5053 | |||
| aa82f13e08 | |||
| e8cd7a4595 | |||
| 568e3583b9 | |||
| 113e609b55 | |||
| edd684cd7c | |||
| 302de1f212 | |||
| d0bf147008 | |||
| 5d7145ff65 | |||
| 2faa760217 | |||
| eb0d0fbb6d | |||
| ccaab5b7e5 | |||
| 2ecfdef874 | |||
| 49e287f987 | |||
| 60c19498e3 | |||
| 9e59dc83fe | |||
| f39aaa7de5 | |||
| 68ae6dc9cb | |||
| 356672c634 | |||
| eff520316e | |||
| fa3012a711 | |||
| 27024721ea | |||
| 50a8b334be | |||
| 402b443f17 | |||
| 220284a892 | |||
| 5d81a1f0f1 | |||
| 5b8e6c64ff | |||
| 4b2edce0e4 | |||
| ff32c639ed | |||
| bad7544cf8 | |||
| a05d72d945 | |||
| 4672332012 | |||
| b4682b462a | |||
| 6ea30eb6d4 | |||
| b451da2141 | |||
| b5517bedcf | |||
| f411c6e3cb | |||
| 5a769cffc8 | |||
| dae72342b4 | |||
| ea47e9043b | |||
| 3b42b1a862 | |||
| e1d7ae94ee | |||
| 1945e03640 | |||
| 00eadbe207 | |||
| ee51cb775d | |||
| 0cf5e8f70d | |||
| 09d60d496b | |||
| b48d52d3bc | |||
| 9849c63d99 | |||
| e332c78512 | |||
| 0a148c10c2 | |||
| cf03403459 | |||
| a7491972e2 | |||
| 21c5cbd624 | |||
| 664c841e8d | |||
| 5f6837ea31 | |||
| 88ae4cfc4c | |||
| 042b314784 | |||
| a43cbd21ce | |||
| 39ca7b3e83 | |||
| 9d0bf7dca7 | |||
| 8913b6e0e2 | |||
| 0631e5953e | |||
| bdc7e85380 | |||
| be071be46b | |||
| b047c9016a | |||
| 8fa6054ada | |||
| c062ae7cf5 | |||
| 1c8b0bf081 | |||
| 5eddda90c5 | |||
| 46ed2f8468 | |||
| ecabbee799 | |||
| 568421c66b | |||
| ed4f6165c6 | |||
| 02f5fc0460 | |||
| a9aedc1236 | |||
| b4c9df4549 | |||
| 4d0b258ed7 | |||
| 71b21855c1 | |||
| f43878571b | |||
| fbe6238009 | |||
| 2ed68db245 | |||
| c81a99c755 | |||
| 3563e195bc | |||
| 47c7cd9ad8 | |||
| 6b9cf6b90c | |||
| 8d5cadcf66 | |||
| 3c2b4c5546 | |||
| 12c1ca36c7 | |||
| 9355c6a590 | |||
| 88e0de8417 | |||
| 8aa67d017c | |||
| 6b6204d264 | |||
| 50142d062e | |||
| b18069893b | |||
| fa414e7ae5 | |||
| 1d48abf3b7 | |||
| 43626a656b | |||
| c5a6e20552 | |||
| b02a55e6a6 | |||
| 176b616773 | |||
| 783822826c | |||
| 25ce040d00 | |||
| 6ae8779f8f | |||
| 7fafa513a2 | |||
| d20a7de308 | |||
| e1a6a85c76 | |||
| 565438eb9f | |||
| efea45f892 | |||
| f0bf6c61ab | |||
| f3b6183449 | |||
| d10e93b56f | |||
| b88afe29b9 | |||
| 13c72935ba | |||
| 7fee53a92a | |||
| 8ee2442b9c | |||
| 99484054f9 | |||
| 3be978fc53 | |||
| fe773941e4 | |||
| 63fc0d9640 | |||
| 4a83adb4f3 | |||
| 3d66271ac8 | |||
| 29cea6f9d3 | |||
| 47ad265fb4 | |||
| 99371ede9e | |||
| 6e8884d1d1 | |||
| 2c95b4e6ba | |||
| 4b3fb8f584 | |||
| 40e9e83e3a | |||
| 59ead448e9 | |||
| 1397e0bb59 | |||
| 56e610d6b0 | |||
| ba3dd5fe7f | |||
| d9699b7fe2 | |||
| ed742de9db | |||
| 8fdc809118 | |||
| dfdd28b869 | |||
| a539235d1a | |||
| df08f255d3 | |||
| 31d5cb6e8e | |||
| d2750dee8a | |||
| 43553ad8ad | |||
| 48b2c0fae0 | |||
| 0988fdca9d | |||
| a24159c3f0 | |||
| f9c9ecf18e | |||
| f93a908d25 | |||
| 1237b5f552 | |||
| bce970de5f | |||
| 8809cd9ddf | |||
| fdbc5fd270 | |||
| 3d5d8d3c9a | |||
| 9d1bbc5d9a | |||
| aee6d2764a | |||
| a26cac3a07 | |||
| 811fc1a5eb | |||
| 1b3b0bd08f | |||
| 7972fd2d46 | |||
| 31e2725566 | |||
| b31695ff58 | |||
| a314692534 | |||
| 9de126bb55 | |||
| f66382e324 | |||
| e2ef4f08a4 | |||
| 1e1b70e59b | |||
| 0ca4b5c197 | |||
| df8eb83abe | |||
| 3f1b22a126 | |||
| b11524c2f9 | |||
| a2333762ea | |||
| 3e2e853022 | |||
| 27904be912 | |||
| c9d3b56346 | |||
| db485d1ff2 | |||
| 707c7a42e1 | |||
| 456016a585 | |||
| a38ddbb53a | |||
| 5a73173dcf | |||
| 7abdccf284 | |||
| a34a943397 | |||
| fe4601bb8b | |||
| 86a56f4cff | |||
| c3493a7335 | |||
| b2a102023b | |||
| 2a85dc37c3 | |||
| 46f2397cdc | |||
| 57d4665b62 | |||
| cf3943bc08 | |||
| 1da1392670 | |||
| 095b0d967d | |||
| 16c1764e73 | |||
| 453a0b9c77 | |||
| fd051dbf74 | |||
| 2eb8500799 | |||
| e1b075520b | |||
| 0477a319b4 | |||
| 7eaa7a1f46 | |||
| cdfe882322 | |||
| 2ff02a15bf | |||
| 09f53b1b63 | |||
| d0022aa0cb | |||
| 632c0662e4 | |||
| e8ee494e13 | |||
| fdaa8f8961 | |||
| aa645778e3 | |||
| aca71922e8 | |||
| 08b96bdd39 | |||
| 89d8c2cb7a | |||
| 004334f642 | |||
| 60d0f2ed30 | |||
| d82a12d8c8 | |||
| 7b190bf882 | |||
| 18763f1df0 | |||
| 486329be24 | |||
| c0c8d7d5da | |||
| 8cbf37b29b | |||
| 43affdc543 | |||
| b6afde2990 | |||
| e28123fb3c | |||
| 79717cae5c | |||
| 6fe3407fae | |||
| 8d0dff2224 | |||
| 8047c6f6fe | |||
| c6bdaca89c | |||
| 8e10065c25 | |||
| cd592be772 | |||
| 1a90c1347e | |||
| 0e3d300390 | |||
| e5507140c8 | |||
| cd43f73b88 | |||
| 8e026bea78 | |||
| a5308b85da | |||
| ed522d51a5 | |||
| d9c31820e0 | |||
| eb60a63200 | |||
| 58ca234a37 | |||
| ff2cd6e384 | |||
| 2012b6f5af | |||
| 889fc4701e | |||
| 74a71b36dc | |||
| ae0b5e8f9a | |||
| e44c1d675e | |||
| 61bd5f7a96 | |||
| faf827f248 | |||
| d59e37812d | |||
| 51dd7dc6fb | |||
| 2c2326a4a9 | |||
| fb34c1525d | |||
| d496046d50 | |||
| 1c5b47ab52 | |||
| 87f015341e | |||
| 6087a940c6 | |||
| be82ad0b69 | |||
| 88271276fc | |||
| 456e434474 | |||
| b28525d718 | |||
| a820277f25 | |||
| 10883353f2 | |||
| 6de67f7fb3 | |||
| b08161f9ec | |||
| c35e973524 | |||
| f985ea2999 | |||
| e42e91a1e0 | |||
| 08eb6089e1 | |||
| dd93f6e66d | |||
| b6989336e7 | |||
| 79c6fc3bcb | |||
| f61a7d83ce |
@@ -1,9 +1,18 @@
|
||||
--ignore-dir=.idea
|
||||
--ignore-dir=.cache
|
||||
--ignore-dir=vendor
|
||||
--ignore-dir=yoeunes
|
||||
--ignore-dir=node_modules
|
||||
|
||||
--ignore-dir=demo/laravel/vendor
|
||||
--ignore-dir=demo/laravel/node_modules
|
||||
--ignore-dir=demo/laravel/storage
|
||||
--ignore-dir=demo/laravel/bootstrap/cache
|
||||
|
||||
--ignore-dir=demo/symfony/vendor
|
||||
--ignore-dir=.cache
|
||||
--ignore-dir=demo/symfony/node_modules
|
||||
--ignore-dir=demo/symfony/var
|
||||
|
||||
--ignore-dir=docs/.jekyll-cache
|
||||
--ignore-dir=docs/_site
|
||||
--ignore-dir=docs/node_modules
|
||||
|
||||
@@ -85,6 +85,25 @@
|
||||
"contributions": [
|
||||
"design"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "AhmedGamal",
|
||||
"name": "Ahmed Gamal",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/11786167?v=4",
|
||||
"profile": "https://github.com/AhmedGamal",
|
||||
"contributions": [
|
||||
"code",
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "BrookeDot",
|
||||
"name": "Brooke.",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/150348?v=4",
|
||||
"profile": "https://github.com/BrookeDot",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
> 1%
|
||||
last 2 versions
|
||||
not dead
|
||||
not IE 11
|
||||
|
||||
@@ -1,2 +1 @@
|
||||
github: yoeunes
|
||||
custom: https://www.paypal.com/paypalme/yoeunes
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
name: 🚀 Publish assets to NPM
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [ published ]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
name: Run Tests Before Publishing
|
||||
|
||||
steps:
|
||||
- name: 📥 Checkout Code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: 🔧 Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20.x'
|
||||
cache: 'npm'
|
||||
|
||||
- name: 📦 Install Dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: ✅ Run Tests
|
||||
run: npm run test
|
||||
|
||||
publish-prime:
|
||||
needs: test
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./src/Prime/Resources
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20.x'
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
|
||||
- name: Publish to NPM
|
||||
run: npm publish --access public
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
publish-plugin:
|
||||
needs: test
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
path:
|
||||
- ./src/Noty/Prime/Resources
|
||||
- ./src/Notyf/Prime/Resources
|
||||
- ./src/SweetAlert/Prime/Resources
|
||||
- ./src/Toastr/Prime/Resources
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20.x'
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
working-directory: ${{ matrix.path }}
|
||||
|
||||
- name: Publish to NPM
|
||||
run: npm publish --access public
|
||||
working-directory: ${{ matrix.path }}
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
@@ -0,0 +1,233 @@
|
||||
name: qa
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- 2.x
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: '0 0 * * *' # Daily at midnight
|
||||
|
||||
jobs:
|
||||
javascript-tests:
|
||||
runs-on: ubuntu-latest
|
||||
name: JavaScript Tests
|
||||
|
||||
steps:
|
||||
- name: 📥 Checkout Code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: 🔧 Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20.x'
|
||||
cache: 'npm'
|
||||
|
||||
- name: 📦 Install Dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: ✅ Run Tests
|
||||
run: npm run test
|
||||
|
||||
- name: 📊 Run Coverage
|
||||
run: npm run test:coverage
|
||||
|
||||
static-analysis:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
php: [ 8.2 ]
|
||||
|
||||
name: php v${{ matrix.php }}
|
||||
|
||||
steps:
|
||||
- name: 📥 Checkout Code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: 🔧 Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
coverage: none
|
||||
|
||||
- name: 🚚 Cache Composer Dependencies
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.composer/cache
|
||||
key: ${{ runner.os }}-composer-${{ matrix.php }}-${{ hashFiles('composer.json') }}
|
||||
restore-keys: ${{ runner.os }}-composer-${{ matrix.php }}-
|
||||
|
||||
- name: 📦 Install Dependencies
|
||||
run: |
|
||||
composer config --global allow-plugins true
|
||||
composer install --no-interaction --prefer-dist --optimize-autoloader
|
||||
|
||||
- name: 🧹 Run PHP CS Fixer (Code Style)
|
||||
run: vendor/bin/php-cs-fixer fix --dry-run --diff
|
||||
|
||||
- name: 🔍 Run PHPStan (Static Analysis)
|
||||
run: vendor/bin/phpstan analyse --no-progress
|
||||
|
||||
- name: 🚀 Run PHPLint (Syntax Check)
|
||||
run: vendor/bin/phplint
|
||||
|
||||
prime-test:
|
||||
needs: static-analysis
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- { php: 8.4, phpunit: 10.5.* }
|
||||
- { php: 8.3, phpunit: 10.5.* }
|
||||
- { php: 8.2, phpunit: 10.5.* }
|
||||
|
||||
name: php v${{ matrix.php }}
|
||||
|
||||
steps:
|
||||
- name: 📥 Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: 🔧 Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
coverage: none
|
||||
|
||||
- name: 🚚 Cache dependencies
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.composer/cache
|
||||
key: ${{ runner.os }}-composer-${{ matrix.php }}-${{ hashFiles('composer.json') }}
|
||||
restore-keys: ${{ runner.os }}-composer-${{ matrix.php }}-
|
||||
|
||||
- name: 📦 Install dependencies
|
||||
run: |
|
||||
sed -i '/"require": {/,/},/d; /"require-dev": {/,/},/d' composer.json
|
||||
composer config --global allow-plugins true
|
||||
composer require "phpunit/phpunit:${{ matrix.phpunit }}" "mockery/mockery" "psr/container" --no-interaction --no-update
|
||||
composer update --prefer-lowest -W --no-interaction --prefer-dist --optimize-autoloader
|
||||
|
||||
- name: ✅ Execute tests
|
||||
run: vendor/bin/phpunit --testsuite prime
|
||||
|
||||
symfony-test:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- { symfony: 8.0.x-dev, php: 8.4, phpunit: 10.5.* }
|
||||
- { symfony: 7.4.x-dev, php: 8.2, phpunit: 10.5.* }
|
||||
- { symfony: 7.3.*, php: 8.5, phpunit: 10.5.* }
|
||||
- { symfony: 7.3.*, php: 8.4, phpunit: 10.5.* }
|
||||
- { symfony: 7.3.*, php: 8.3, phpunit: 10.5.* }
|
||||
- { symfony: 7.3.*, php: 8.2, phpunit: 10.5.* }
|
||||
- { symfony: 7.2.*, php: 8.2, phpunit: 10.5.* }
|
||||
- { symfony: 7.1.*, php: 8.2, phpunit: 10.5.* }
|
||||
- { symfony: 7.0.*, php: 8.2, phpunit: 10.5.* }
|
||||
|
||||
name: symfony v${{ matrix.symfony }} x php v${{ matrix.php }}
|
||||
|
||||
steps:
|
||||
- name: 📥 Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: 🔧 Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
coverage: none
|
||||
|
||||
- name: 🚚 Cache dependencies
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.composer/cache
|
||||
key: ${{ runner.os }}-composer-${{ matrix.php }}-${{ hashFiles('composer.json') }}
|
||||
restore-keys: ${{ runner.os }}-composer-${{ matrix.php }}-
|
||||
|
||||
- name: 📦 Install dependencies
|
||||
run: |
|
||||
sed -i '/"require": {/,/},/d; /"require-dev": {/,/},/d' composer.json
|
||||
composer config --global allow-plugins true
|
||||
composer config extra.symfony.require "${{ matrix.symfony }}"
|
||||
|
||||
if [[ "${{ matrix.symfony }}" == *"-dev"* ]]; then
|
||||
echo "Setting minimum-stability to dev for ${{ matrix.symfony }}"
|
||||
composer config minimum-stability "dev"
|
||||
composer config prefer-stable true
|
||||
fi
|
||||
|
||||
composer require "symfony/config:${{ matrix.symfony }}" "symfony/console:${{ matrix.symfony }}" "symfony/dependency-injection:${{ matrix.symfony }}" "symfony/framework-bundle:${{ matrix.symfony }}" "symfony/http-kernel:${{ matrix.symfony }}" "symfony/translation:${{ matrix.symfony }}" "symfony/twig-bundle:${{ matrix.symfony }}" "phpunit/phpunit:${{ matrix.phpunit }}" "mockery/mockery" "psr/container" "monolog/monolog" --no-interaction --no-update
|
||||
|
||||
if [[ "${{ matrix.symfony }}" == *"-dev"* ]]; then
|
||||
echo "Running composer update (latest dependencies)"
|
||||
composer update -W --no-interaction --prefer-dist --optimize-autoloader
|
||||
else
|
||||
echo "Running composer update --prefer-lowest"
|
||||
composer update --prefer-lowest -W --no-interaction --prefer-dist --optimize-autoloader
|
||||
fi
|
||||
|
||||
- name: ✅ Execute tests
|
||||
run: vendor/bin/phpunit --testsuite symfony
|
||||
|
||||
laravel-test:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- { laravel: 13.x-dev, testbench: 11.x-dev, php: 8.5, phpunit: 11.5.* }
|
||||
- { laravel: 13.x-dev, testbench: 11.x-dev, php: 8.4, phpunit: 11.5.* }
|
||||
- { laravel: 13.x-dev, testbench: 11.x-dev, php: 8.3, phpunit: 11.5.* }
|
||||
- { laravel: 12.*, testbench: 10.*, php: 8.5, phpunit: 11.5.* }
|
||||
- { laravel: 12.*, testbench: 10.*, php: 8.4, phpunit: 11.5.* }
|
||||
- { laravel: 12.*, testbench: 10.*, php: 8.3, phpunit: 11.5.* }
|
||||
- { laravel: 12.*, testbench: 10.*, php: 8.2, phpunit: 11.5.* }
|
||||
- { laravel: 11.*, testbench: 9.*, php: 8.2, phpunit: 10.5.* }
|
||||
|
||||
name: laravel v${{ matrix.laravel }} x php v${{ matrix.php }}
|
||||
|
||||
steps:
|
||||
- name: 📥 Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: 🔧 Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
extensions: fileinfo
|
||||
coverage: none
|
||||
|
||||
- name: 🚚 Cache dependencies
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.composer/cache
|
||||
key: ${{ matrix.php }}-composer-${{ hashFiles('composer.json') }}
|
||||
restore-keys: ${{ matrix.php }}-composer
|
||||
|
||||
- name: 📦 Install dependencies
|
||||
run: |
|
||||
sed -i '/\"require\": {/,/},/d; /\"require-dev\": {/,/},/d' composer.json
|
||||
composer config --global allow-plugins true
|
||||
|
||||
if [[ "${{ matrix.laravel }}" == *"-dev"* ]]; then
|
||||
echo "Setting minimum-stability to dev for ${{ matrix.laravel }}"
|
||||
composer config minimum-stability "dev"
|
||||
composer config prefer-stable true
|
||||
fi
|
||||
|
||||
composer require "laravel/framework:${{ matrix.laravel }}" "phpunit/phpunit:${{ matrix.phpunit }}" "orchestra/testbench:${{ matrix.testbench }}" --no-interaction --no-update
|
||||
|
||||
if [[ "${{ matrix.laravel }}" == *"-dev"* ]]; then
|
||||
echo "Running composer update (latest dependencies)"
|
||||
composer update -W --no-interaction --prefer-dist --optimize-autoloader
|
||||
else
|
||||
echo "Running composer update --prefer-lowest"
|
||||
composer update --prefer-lowest -W --no-interaction --prefer-dist --optimize-autoloader
|
||||
fi
|
||||
|
||||
- name: ✅ Execute tests
|
||||
run: vendor/bin/phpunit --testsuite laravel
|
||||
+19
-17
@@ -1,22 +1,24 @@
|
||||
.idea/
|
||||
.DS_Store
|
||||
/.idea/
|
||||
/.DS_Store
|
||||
|
||||
vendor/
|
||||
node_modules/
|
||||
/vendor/
|
||||
/node_modules/
|
||||
|
||||
.cache/php-cs-fixer/
|
||||
.cache/phpunit/
|
||||
.cache/phpstan/
|
||||
.cache/phplint/
|
||||
.cache/nx/
|
||||
.nx/
|
||||
/coverage/
|
||||
|
||||
.php-cs-fixer.php
|
||||
phpunit.xml
|
||||
taskfile.yml
|
||||
phpstan.neon
|
||||
/.cache/php-cs-fixer/
|
||||
/.cache/phplint/
|
||||
/.cache/phpstan/
|
||||
/.cache/phpunit/
|
||||
|
||||
lerna-debug.log
|
||||
npm-debug.log
|
||||
/.php-cs-fixer.php
|
||||
/phpunit.xml
|
||||
/taskfile.yml
|
||||
/phpstan.neon
|
||||
|
||||
tests/Symfony/Fixtures/project/public/vendor/
|
||||
/npm-debug.log
|
||||
|
||||
/tests/Symfony/Fixtures/project/public/vendor/
|
||||
|
||||
src/**/vendor/
|
||||
src/**/composer.lock
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
{
|
||||
"upgrade": true,
|
||||
"target": "semver"
|
||||
"upgrade": true,
|
||||
"target": "semver",
|
||||
"format": "group",
|
||||
"color": true,
|
||||
"root": true
|
||||
}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
*.log
|
||||
npm-debug.log*
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
||||
# Dependency directories
|
||||
node_modules
|
||||
@@ -2,7 +2,11 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
$finder = PhpCsFixer\Finder::create()
|
||||
use PhpCsFixer\Config;
|
||||
use PhpCsFixer\Finder;
|
||||
use PhpCsFixer\Runner\Parallel\ParallelConfigFactory;
|
||||
|
||||
$finder = Finder::create()
|
||||
->in([
|
||||
__DIR__.'/src',
|
||||
__DIR__.'/tests',
|
||||
@@ -11,7 +15,8 @@ $finder = PhpCsFixer\Finder::create()
|
||||
->append([__FILE__])
|
||||
;
|
||||
|
||||
return (new PhpCsFixer\Config())
|
||||
return (new Config())
|
||||
->setParallelConfig(ParallelConfigFactory::detect())
|
||||
->setRiskyAllowed(true)
|
||||
->setRules([
|
||||
'@PSR12' => true,
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
pnpm-lock.yaml
|
||||
pnpm-workspace.yaml
|
||||
|
||||
**/node_modules
|
||||
src/**/Resources/public/**
|
||||
src/**/Resources/dist/**
|
||||
|
||||
Vendored
-1
@@ -1,2 +1 @@
|
||||
github: yoeunes
|
||||
custom: https://www.paypal.com/paypalme/yoeunes
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
Please do not submit any Pull Requests here. They will be closed.
|
||||
---
|
||||
|
||||
Please submit your PR here instead:
|
||||
https://github.com/php-flasher/php-flasher
|
||||
|
||||
This repository is what we call a "subtree split": a read-only subset of that main repository.
|
||||
We're looking forward to your PR there!
|
||||
-23
@@ -1,23 +0,0 @@
|
||||
name: Auto Closer PR
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [ opened ]
|
||||
|
||||
jobs:
|
||||
run:
|
||||
name: 🤖 PR Auto-Closure
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: superbrothers/close-pull-request@v3
|
||||
with:
|
||||
comment: |
|
||||
Hi there 👋,
|
||||
|
||||
First off, thanks for your effort! 🎉 Unfortunately, this repository is read-only because it's split from our primary monorepo repository.
|
||||
|
||||
🙏 We kindly ask if you could direct your valuable contribution to our main repository at https://github.com/php-flasher/php-flasher.
|
||||
|
||||
Once you've moved your contribution there, we'll review it and provide feedback. 🕵️♂️
|
||||
|
||||
Thanks again for your understanding and cooperation. We really appreciate it! 🙌
|
||||
@@ -0,0 +1,20 @@
|
||||
name: Close Pull Request
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened]
|
||||
|
||||
jobs:
|
||||
run:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: superbrothers/close-pull-request@v3
|
||||
with:
|
||||
comment: |
|
||||
Thanks for your Pull Request! We love contributions.
|
||||
|
||||
However, you should instead open your PR on the main repository:
|
||||
https://github.com/php-flasher/php-flasher
|
||||
|
||||
This repository is what we call a "subtree split": a read-only subset of that main repository.
|
||||
We're looking forward to your PR there!
|
||||
+45
-5
@@ -1,10 +1,50 @@
|
||||
# CHANGELOG for 2.x
|
||||
|
||||
## [Unreleased](https://github.com/php-flasher/php-flasher/compare/v2.0.1...2.x)
|
||||
## [Unreleased](https://github.com/php-flasher/php-flasher/compare/v2.1.4...2.x)
|
||||
|
||||
* feature [Flasher] Add event dispatching system for all notification adapters and themes with Livewire integration:
|
||||
- [Toastr] Dispatch events: `flasher:toastr:click`, `flasher:toastr:close`, `flasher:toastr:show`, `flasher:toastr:hidden`
|
||||
- [Noty] Dispatch events: `flasher:noty:click`, `flasher:noty:close`, `flasher:noty:show`, `flasher:noty:hover`
|
||||
- [Notyf] Dispatch events: `flasher:notyf:click`, `flasher:notyf:dismiss`
|
||||
- [Themes] Dispatch events: `flasher:theme:click` (generic) and `flasher:theme:{name}:click` (specific)
|
||||
- [Laravel] Add LivewireListener classes for all adapters and themes to enable Livewire event handling
|
||||
|
||||
## [v2.1.3](https://github.com/php-flasher/php-flasher/compare/v2.1.2...v2.1.3) - 2025-01-25
|
||||
|
||||
* bug [#208](https://github.com/php-flasher/php-flasher/issues/208) [Flasher] Add GitHub workflow for automatic publishing of assets to NPM. See [PR #211](https://github.com/php-flasher/php-flasher/pull/211) by [ToshY](https://github.com/ToshY)
|
||||
|
||||
## [v2.1.2](https://github.com/php-flasher/php-flasher/compare/v2.1.1...v2.1.2) - 2025-01-18
|
||||
|
||||
* bug [#208](https://github.com/php-flasher/php-flasher/issues/208) [Flasher] Allow `main_script` to be nullable. See [PR #209](https://github.com/php-flasher/php-flasher/pull/209) by [yoeunes](https://github.com/yoeunes)
|
||||
|
||||
## [v2.1.1](https://github.com/php-flasher/php-flasher/compare/v2.1.0...v2.1.1) - 2024-10-20
|
||||
|
||||
* feature [Laravel] Add `excluded_paths` option. See [PR #203](https://github.com/php-flasher/php-flasher/pull/203) by [yoeunes](https://github.com/yoeunes)
|
||||
|
||||
## [v2.1.0](https://github.com/php-flasher/php-flasher/compare/v2.0.4...v2.1.0) - 2024-10-19
|
||||
|
||||
* feature [Flasher] Update laravel and symfony configuration documentation . See [PR #201](https://github.com/php-flasher/php-flasher/pull/201) by [yoeunes](https://github.com/yoeunes)
|
||||
* feature [Flasher] Improve Type Safety and IDE Support with Enhanced PHPDoc Annotations and Stricter PHPStan Validations. See [PR #200](https://github.com/php-flasher/php-flasher/pull/200) by [yoeunes](https://github.com/yoeunes)
|
||||
* feature [Symfony] Improve configuration descriptions and add examples. See [PR #199](https://github.com/php-flasher/php-flasher/pull/199) by [yoeunes](https://github.com/yoeunes)
|
||||
* feature [Symfony] Add Symfony Profiler integration for PHPFlasher. See [PR #198](https://github.com/php-flasher/php-flasher/pull/198) by [yoeunes](https://github.com/yoeunes)
|
||||
|
||||
## [v2.0.4](https://github.com/php-flasher/php-flasher/compare/v2.0.3...v2.0.4) - 2024-09-22
|
||||
|
||||
* bug [laravel] Changed HttpKernel import from `Illuminate\Foundation\Http\Kernel` to `Illuminate\Contracts\Http\Kernel` to use the contract interface instead of the concrete implementation. See [PR #197](https://github.com/php-flasher/php-flasher/pull/197) by [yoeunes](https://github.com/yoeunes)
|
||||
|
||||
## [v2.0.3](https://github.com/php-flasher/php-flasher/compare/v2.0.2...v2.0.3) - 2024-09-21
|
||||
|
||||
* remove border from flasher container by [yoeunes](https://github.com/yoeunes)
|
||||
|
||||
## [v2.0.2](https://github.com/php-flasher/php-flasher/compare/v2.0.1...v2.0.2) - 2024-09-19
|
||||
|
||||
* feature [Flasher] add escapeHtml option for secure HTML escaping in notifications. See [PR #196](https://github.com/php-flasher/php-flasher/pull/196) by [yoeunes](https://github.com/yoeunes)
|
||||
* feature [Flasher] add Default configuration options. See [PR #183](https://github.com/php-flasher/php-flasher/pull/183) by [AhmedGamal](https://github.com/AhmedGamal)
|
||||
* feature [Laravel] Refactor middleware to use Symfony's base response class, addressing compatibility issues. See [PR #184](https://github.com/php-flasher/php-flasher/pull/184) by [yoeunes](https://github.com/yoeunes)
|
||||
|
||||
## [v2.0.1](https://github.com/php-flasher/php-flasher/compare/v2.0.0...v2.0.1) - 2024-05-23
|
||||
|
||||
* bug [#176](https://github.com/php-flasher/php-flasher/issues/176) [Laravel] Correctly disable FlasherMiddleware when `inject_assets` is set to false. See [PR #177](https://github.com/php-flasher/php-flasher/pull/177)
|
||||
* bug [#176](https://github.com/php-flasher/php-flasher/issues/176) [Flasher] Ensure global `timeout` option applies to all requests. See [PR #180](https://github.com/php-flasher/php-flasher/pull/180)
|
||||
* bug [#176](https://github.com/php-flasher/php-flasher/issues/176) [Laravel] Allow disabling of default flash replacement by setting `flash_bag` to false. See [PR #181](https://github.com/php-flasher/php-flasher/pull/181)
|
||||
* bug [#176](https://github.com/php-flasher/php-flasher/issues/176) [Flasher] Ensure `flash_bag` option overrides default values instead of appending. See [PR #182](https://github.com/php-flasher/php-flasher/pull/182)
|
||||
* bug [#176](https://github.com/php-flasher/php-flasher/issues/176) [Laravel] Correctly disable FlasherMiddleware when `inject_assets` is set to false. See [PR #177](https://github.com/php-flasher/php-flasher/pull/177) by [yoeunes](https://github.com/yoeunes)
|
||||
* bug [#176](https://github.com/php-flasher/php-flasher/issues/176) [Flasher] Ensure global `timeout` option applies to all requests. See [PR #180](https://github.com/php-flasher/php-flasher/pull/180) by [yoeunes](https://github.com/yoeunes)
|
||||
* bug [#176](https://github.com/php-flasher/php-flasher/issues/176) [Laravel] Allow disabling of default flash replacement by setting `flash_bag` to false. See [PR #181](https://github.com/php-flasher/php-flasher/pull/181) by [yoeunes](https://github.com/yoeunes)
|
||||
* bug [#176](https://github.com/php-flasher/php-flasher/issues/176) [Flasher] Ensure `flash_bag` option overrides default values instead of appending. See [PR #182](https://github.com/php-flasher/php-flasher/pull/182) by [yoeunes](https://github.com/yoeunes)
|
||||
|
||||
@@ -1,74 +1,338 @@
|
||||
<div align="center">
|
||||
<a href="https://github.com/php-flasher/php-flasher/blob/2.x/docs/palestine.md">
|
||||
<img src="https://raw.githubusercontent.com/php-flasher/art/main/palestine-banner-support.svg" width="800px" alt="Help Palestine"/>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<p align="center">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/php-flasher/art/main/php-flasher-github-dark.png">
|
||||
<img src="https://raw.githubusercontent.com/php-flasher/art/main/php-flasher-github.png" alt="PHPFlasher Logo">
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/php-flasher/art/main/php-flasher-logo-dark.png">
|
||||
<img src="https://raw.githubusercontent.com/php-flasher/art/main/php-flasher-logo.png" alt="PHPFlasher Logo">
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
## About PHPFlasher
|
||||
<h1 align="center">Elegant Flash Notifications for PHP</h1>
|
||||
|
||||
PHPFlasher is a powerful and easy-to-use package that allows you to quickly and easily add flash messages to your Laravel or Symfony projects.
|
||||
Whether you need to alert users of a successful form submission, an error, or any other important information, flash messages are a simple and effective solution for providing feedback to your users.
|
||||
<p align="center">
|
||||
<strong>One line of PHP. Beautiful notifications. Zero JavaScript.</strong>
|
||||
</p>
|
||||
|
||||
With PHPFlasher, you can easily record and store messages within the session, making it simple to retrieve and display them on the current or next page.
|
||||
This improves user engagement and enhances the overall user experience on your website or application.
|
||||
<p align="center">
|
||||
<a href="https://packagist.org/packages/php-flasher/flasher"><img src="https://img.shields.io/packagist/dt/php-flasher/flasher.svg?style=flat-square&label=downloads" alt="Downloads"></a>
|
||||
<a href="https://github.com/php-flasher/php-flasher"><img src="https://img.shields.io/github/stars/php-flasher/php-flasher.svg?style=flat-square&label=stars" alt="Stars"></a>
|
||||
<a href="https://github.com/php-flasher/php-flasher/releases"><img src="https://img.shields.io/github/v/release/php-flasher/flasher.svg?style=flat-square" alt="Release"></a>
|
||||
<a href="https://packagist.org/packages/php-flasher/flasher"><img src="https://img.shields.io/packagist/php-v/php-flasher/flasher.svg?style=flat-square" alt="PHP Version"></a>
|
||||
<a href="https://github.com/php-flasher/flasher/blob/master/LICENSE"><img src="https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square" alt="License"></a>
|
||||
</p>
|
||||
|
||||
Whether you're a beginner or an experienced developer, PHPFlasher's intuitive and straightforward design makes it easy to integrate into your projects.
|
||||
So, if you're looking for a reliable, flexible and easy to use flash messages solution, PHPFlasher is the perfect choice.
|
||||
<p align="center">
|
||||
<a href="https://php-flasher.io"><strong>Documentation</strong></a> ·
|
||||
<a href="https://php-flasher.io/playground"><strong>Live Playground</strong></a> ·
|
||||
<a href="https://github.com/php-flasher/php-flasher/issues"><strong>Report Bug</strong></a>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
## Official Documentation
|
||||
## Quick Start
|
||||
|
||||
Documentation for PHPFlasher can be found on the [https://php-flasher.io](https://php-flasher.io).
|
||||
**Laravel:**
|
||||
```bash
|
||||
composer require php-flasher/flasher-laravel && php artisan flasher:install
|
||||
```
|
||||
|
||||
## Contributors and sponsors
|
||||
**Symfony:**
|
||||
```bash
|
||||
composer require php-flasher/flasher-symfony && php bin/console flasher:install
|
||||
```
|
||||
|
||||
Join our team of contributors and make a lasting impact on our project!
|
||||
**That's it!** Now use it:
|
||||
|
||||
We are always looking for passionate individuals who want to contribute their skills and ideas.
|
||||
Whether you're a developer, designer, or simply have a great idea, we welcome your participation and collaboration.
|
||||
```php
|
||||
flash()->success('Welcome aboard! Your account is ready.');
|
||||
```
|
||||
|
||||
Shining stars of our community:
|
||||
---
|
||||
|
||||
<!-- ALL-CONTRIBUTORS-LIST:START -->
|
||||
<!-- prettier-ignore-start -->
|
||||
<!-- markdownlint-disable -->
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://www.linkedin.com/in/younes-ennaji/"><img src="https://avatars.githubusercontent.com/u/10859693?v=4?s=100" width="100px;" alt="Younes ENNAJI"/><br /><sub><b>Younes ENNAJI</b></sub></a><br /><a href="https://github.com/php-flasher/php-flasher/commits?author=yoeunes" title="Code">💻</a> <a href="https://github.com/php-flasher/php-flasher/commits?author=yoeunes" title="Documentation">📖</a> <a href="#maintenance-yoeunes" title="Maintenance">🚧</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/salmayno"><img src="https://avatars.githubusercontent.com/u/27933199?v=4?s=100" width="100px;" alt="Salma Mourad"/><br /><sub><b>Salma Mourad</b></sub></a><br /><a href="#financial-salmayno" title="Financial">💵</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://www.youtube.com/rstacode"><img src="https://avatars.githubusercontent.com/u/35005761?v=4?s=100" width="100px;" alt="Nashwan Abdullah"/><br /><sub><b>Nashwan Abdullah</b></sub></a><br /><a href="#financial-codenashwan" title="Financial">💵</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://darvis.nl/"><img src="https://avatars.githubusercontent.com/u/7394837?v=4?s=100" width="100px;" alt="Arvid de Jong"/><br /><sub><b>Arvid de Jong</b></sub></a><br /><a href="#financial-darviscommerce" title="Financial">💵</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://ashallendesign.co.uk/"><img src="https://avatars.githubusercontent.com/u/39652331?v=4?s=100" width="100px;" alt="Ash Allen"/><br /><sub><b>Ash Allen</b></sub></a><br /><a href="#design-ash-jc-allen" title="Design">🎨</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://about.me/murrant"><img src="https://avatars.githubusercontent.com/u/39462?v=4?s=100" width="100px;" alt="Tony Murray"/><br /><sub><b>Tony Murray</b></sub></a><br /><a href="https://github.com/php-flasher/php-flasher/commits?author=murrant" title="Code">💻</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://github.com/n3wborn"><img src="https://avatars.githubusercontent.com/u/10246722?v=4?s=100" width="100px;" alt="Stéphane P"/><br /><sub><b>Stéphane P</b></sub></a><br /><a href="https://github.com/php-flasher/php-flasher/commits?author=n3wborn" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://www.instagram.com/lucas.maciel_z"><img src="https://avatars.githubusercontent.com/u/80225404?v=4?s=100" width="100px;" alt="Lucas Maciel"/><br /><sub><b>Lucas Maciel</b></sub></a><br /><a href="#design-LucasStorm" title="Design">🎨</a></td>
|
||||
<td align="center" valign="top" width="14.28%"><a href="https://siek.io/"><img src="https://avatars.githubusercontent.com/u/5730766?v=4?s=100" width="100px;" alt="Antoni Siek"/><br /><sub><b>Antoni Siek</b></sub></a><br /><a href="https://github.com/php-flasher/php-flasher/commits?author=ImJustToNy" title="Code">💻</a></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
## Why PHPFlasher?
|
||||
|
||||
<!-- markdownlint-restore -->
|
||||
<!-- prettier-ignore-end -->
|
||||
| | PHPFlasher | Others |
|
||||
|---|:---:|:---:|
|
||||
| **Zero JavaScript** | Write PHP only, frontend handled automatically | Requires manual JS setup |
|
||||
| **Auto Asset Injection** | CSS/JS injected automatically | Manual script tags needed |
|
||||
| **26 Built-in Themes** | Amazon, iOS, Slack, Material & more | Limited or no themes |
|
||||
| **4 Notification Libraries** | Toastr, SweetAlert, Noty, Notyf | Single library only |
|
||||
| **Livewire Integration** | Full event system support | Limited or none |
|
||||
| **RTL Support** | Built-in right-to-left | Often missing |
|
||||
| **Framework Agnostic** | Laravel, Symfony, or vanilla PHP | Framework-specific |
|
||||
|
||||
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
||||
---
|
||||
|
||||
## Contact
|
||||
## Notification Types
|
||||
|
||||
PHPFlasher is being actively developed by <a href="https://github.com/yoeunes">yoeunes</a>.
|
||||
You can reach out with questions, bug reports, or feature requests on any of the following:
|
||||
```php
|
||||
flash()->success('Operation completed successfully!');
|
||||
flash()->error('Oops! Something went wrong.');
|
||||
flash()->warning('Please backup your data before continuing.');
|
||||
flash()->info('A new version is available for download.');
|
||||
```
|
||||
|
||||
- [Github Issues](https://github.com/php-flasher/php-flasher/issues)
|
||||
- [Github](https://github.com/yoeunes)
|
||||
- [Twitter](https://twitter.com/yoeunes)
|
||||
- [Linkedin](https://www.linkedin.com/in/younes-ennaji/)
|
||||
- [Email me directly](mailto:younes.ennaji@gmail.com)
|
||||
### With Titles
|
||||
|
||||
```php
|
||||
flash()->success('Your changes have been saved.', 'Update Complete');
|
||||
flash()->error('Unable to connect to server.', 'Connection Failed');
|
||||
```
|
||||
|
||||
### With Options
|
||||
|
||||
```php
|
||||
flash()->success('Profile updated!', [
|
||||
'position' => 'bottom-right',
|
||||
'timeout' => 10000,
|
||||
]);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 26 Beautiful Themes
|
||||
|
||||
PHPFlasher includes **26 professionally designed themes** ready to use:
|
||||
|
||||
```php
|
||||
flash()->success('Welcome!', ['theme' => 'amazon']);
|
||||
flash()->success('Welcome!', ['theme' => 'ios']);
|
||||
flash()->success('Welcome!', ['theme' => 'slack']);
|
||||
flash()->success('Welcome!', ['theme' => 'material']);
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary><strong>View All Themes</strong></summary>
|
||||
|
||||
| Theme | Style |
|
||||
|-------|-------|
|
||||
| `flasher` | Default clean design |
|
||||
| `amazon` | Amazon-inspired |
|
||||
| `bootstrap` | Bootstrap style |
|
||||
| `ios` | Apple iOS notifications |
|
||||
| `slack` | Slack messaging style |
|
||||
| `material` | Google Material Design |
|
||||
| `tailwind` | Tailwind CSS inspired |
|
||||
| `google` | Google notifications |
|
||||
| `facebook` | Facebook style |
|
||||
| `minimal` | Ultra-clean minimal |
|
||||
| `amber` | Warm amber tones |
|
||||
| `aurora` | Gradient effects |
|
||||
| `crystal` | Transparent design |
|
||||
| `emerald` | Modern green palette |
|
||||
| `jade` | Soft jade colors |
|
||||
| `neon` | Bright attention-grabbing |
|
||||
| `onyx` | Dark mode sleek |
|
||||
| `ruby` | Bold ruby accents |
|
||||
| `sapphire` | Elegant blue style |
|
||||
| `shadow` | Soft shadow effects |
|
||||
| `spectrum` | Colorful spectrum |
|
||||
| `sunset` | Warm sunset colors |
|
||||
| `zen` | Calm minimal design |
|
||||
|
||||
[**See all themes with live demos →**](https://php-flasher.io/themes)
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
## Notification Libraries
|
||||
|
||||
Need more features? Use popular notification libraries:
|
||||
|
||||
### Toastr
|
||||
|
||||
```bash
|
||||
composer require php-flasher/flasher-toastr-laravel
|
||||
```
|
||||
|
||||
```php
|
||||
toastr()->success('Profile saved!', [
|
||||
'positionClass' => 'toast-bottom-right',
|
||||
'progressBar' => true,
|
||||
]);
|
||||
```
|
||||
|
||||
### SweetAlert
|
||||
|
||||
```bash
|
||||
composer require php-flasher/flasher-sweetalert-laravel
|
||||
```
|
||||
|
||||
```php
|
||||
sweetalert()
|
||||
->showDenyButton()
|
||||
->showCancelButton()
|
||||
->warning('Do you want to save changes?');
|
||||
```
|
||||
|
||||
### Noty
|
||||
|
||||
```bash
|
||||
composer require php-flasher/flasher-noty-laravel
|
||||
```
|
||||
|
||||
```php
|
||||
noty()->success('Data synchronized!', [
|
||||
'layout' => 'topCenter',
|
||||
'timeout' => 3000,
|
||||
]);
|
||||
```
|
||||
|
||||
### Notyf
|
||||
|
||||
```bash
|
||||
composer require php-flasher/flasher-notyf-laravel
|
||||
```
|
||||
|
||||
```php
|
||||
notyf()->success('Upload complete!', [
|
||||
'dismissible' => true,
|
||||
'ripple' => true,
|
||||
]);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Livewire Integration
|
||||
|
||||
PHPFlasher integrates seamlessly with Laravel Livewire:
|
||||
|
||||
```php
|
||||
use Livewire\Attributes\On;
|
||||
|
||||
class UserProfile extends Component
|
||||
{
|
||||
public function save()
|
||||
{
|
||||
// Save logic...
|
||||
|
||||
sweetalert()
|
||||
->showDenyButton()
|
||||
->success('Save changes?');
|
||||
}
|
||||
|
||||
#[On('sweetalert:confirmed')]
|
||||
public function onConfirmed(array $payload): void
|
||||
{
|
||||
// User clicked confirm
|
||||
$this->user->save();
|
||||
flash()->success('Profile saved!');
|
||||
}
|
||||
|
||||
#[On('sweetalert:denied')]
|
||||
public function onDenied(array $payload): void
|
||||
{
|
||||
// User clicked deny
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
[**Livewire documentation →**](https://php-flasher.io/livewire)
|
||||
|
||||
---
|
||||
|
||||
## Configuration
|
||||
|
||||
### Laravel
|
||||
|
||||
```php
|
||||
// config/flasher.php
|
||||
return [
|
||||
'default' => 'flasher',
|
||||
'themes' => [
|
||||
'flasher' => [
|
||||
'options' => [
|
||||
'timeout' => 5000,
|
||||
'position' => 'top-right',
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
```
|
||||
|
||||
### Symfony
|
||||
|
||||
```yaml
|
||||
# config/packages/flasher.yaml
|
||||
flasher:
|
||||
default: flasher
|
||||
themes:
|
||||
flasher:
|
||||
options:
|
||||
timeout: 5000
|
||||
position: top-right
|
||||
```
|
||||
|
||||
### Common Options
|
||||
|
||||
| Option | Type | Default | Description |
|
||||
|--------|------|---------|-------------|
|
||||
| `timeout` | int | `5000` | Auto-dismiss delay in ms (0 = sticky) |
|
||||
| `position` | string | `top-right` | `top-right`, `top-left`, `bottom-right`, `bottom-left`, `top-center`, `bottom-center` |
|
||||
| `closeButton` | bool | `true` | Show close button |
|
||||
| `progressBar` | bool | `true` | Show timeout progress bar |
|
||||
| `rtl` | bool | `false` | Right-to-left text direction |
|
||||
| `escapeHtml` | bool | `true` | Escape HTML in messages |
|
||||
|
||||
---
|
||||
|
||||
## Requirements
|
||||
|
||||
| Requirement | Version |
|
||||
|-------------|---------|
|
||||
| PHP | >= 8.2 |
|
||||
| Laravel | >= 11.0 |
|
||||
| Symfony | >= 7.0 |
|
||||
|
||||
---
|
||||
|
||||
## Documentation
|
||||
|
||||
For complete documentation, visit **[php-flasher.io](https://php-flasher.io)**
|
||||
|
||||
- [Installation Guide](https://php-flasher.io/installation)
|
||||
- [Usage & Examples](https://php-flasher.io/usage)
|
||||
- [Themes Gallery](https://php-flasher.io/themes)
|
||||
- [Livewire Integration](https://php-flasher.io/livewire)
|
||||
- [Configuration Reference](https://php-flasher.io/configuration)
|
||||
- [API Reference](https://php-flasher.io/api)
|
||||
|
||||
---
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are welcome! Please see our [Contributing Guide](CONTRIBUTING.md) for details.
|
||||
|
||||
## Contributors
|
||||
|
||||
<a href="https://github.com/php-flasher/php-flasher/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=php-flasher/php-flasher" alt="Contributors" />
|
||||
</a>
|
||||
|
||||
---
|
||||
|
||||
## Support the Project
|
||||
|
||||
If PHPFlasher helps you build better applications, please consider:
|
||||
|
||||
- **[Star this repository](https://github.com/php-flasher/php-flasher)** to show your support
|
||||
- **[Report bugs](https://github.com/php-flasher/php-flasher/issues)** to help improve the library
|
||||
- **[Share on Twitter](https://twitter.com/intent/tweet?text=Check%20out%20PHPFlasher%20-%20beautiful%20flash%20notifications%20for%20PHP!&url=https://github.com/php-flasher/php-flasher)** to spread the word
|
||||
|
||||
---
|
||||
|
||||
## License
|
||||
|
||||
PHPFlasher is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).
|
||||
PHPFlasher is open-source software licensed under the [MIT license](LICENSE).
|
||||
|
||||
<p align="center"> <b>Made with ❤️ by <a href="https://www.linkedin.com/in/younes-ennaji/">Younes ENNAJI</a> </b> </p>
|
||||
<p align="center">
|
||||
<br>
|
||||
<strong>Made with ❤️ by <a href="https://github.com/yoeunes">Younes ENNAJI</a></strong>
|
||||
<br><br>
|
||||
<a href="https://github.com/php-flasher/php-flasher/stargazers">⭐ Star if you find this useful!</a>
|
||||
</p>
|
||||
|
||||
Executable
+675
@@ -0,0 +1,675 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# =========================================================================
|
||||
# Build System for PHP-Flasher
|
||||
# =========================================================================
|
||||
#
|
||||
# This script provides an elegant build process for PHP-Flasher assets
|
||||
# with comprehensive reporting and flexible configuration options.
|
||||
#
|
||||
# Author: Younes ENNAJI
|
||||
# =========================================================================
|
||||
|
||||
# Strict error handling
|
||||
set -o pipefail
|
||||
|
||||
# =========================================================================
|
||||
# CONSTANTS AND CONFIGURATION
|
||||
# =========================================================================
|
||||
|
||||
# Colors and styles
|
||||
readonly RESET='\033[0m'
|
||||
readonly BOLD='\033[1m'
|
||||
readonly DIM='\033[2m'
|
||||
readonly UNDERLINE='\033[4m'
|
||||
readonly BLUE='\033[34m'
|
||||
readonly GREEN='\033[32m'
|
||||
readonly RED='\033[31m'
|
||||
readonly YELLOW='\033[33m'
|
||||
readonly CYAN='\033[36m'
|
||||
readonly MAGENTA='\033[35m'
|
||||
readonly WHITE='\033[37m'
|
||||
|
||||
# Emoji indicators
|
||||
readonly ROCKET="🚀"
|
||||
readonly PACKAGE="📦"
|
||||
readonly CHECK="✓"
|
||||
readonly ERROR="❌"
|
||||
readonly WARNING="⚠️"
|
||||
readonly HAMMER="🏗️"
|
||||
readonly CHART="📊"
|
||||
readonly SPARKLES="✨"
|
||||
readonly HOURGLASS="⏳"
|
||||
readonly PALETTE="🎨"
|
||||
|
||||
# File paths
|
||||
readonly SRC_DIR="src"
|
||||
readonly PRIME_PATH="${SRC_DIR}/Prime/Resources"
|
||||
readonly TEMP_DIR="/tmp/php-flasher-build-$$"
|
||||
readonly BUILD_LOG="${TEMP_DIR}/build.log"
|
||||
readonly SIZE_DATA="${TEMP_DIR}/sizes.data"
|
||||
|
||||
# Default configuration
|
||||
VERBOSE=false
|
||||
WATCH_MODE=false
|
||||
THEME_ONLY=false
|
||||
MODULE_ONLY=false
|
||||
ANALYZE=false
|
||||
DEEP_ANALYZE=false
|
||||
SKIP_CLEAR=false
|
||||
NODE_ENV="production"
|
||||
|
||||
# =========================================================================
|
||||
# UTILITY FUNCTIONS
|
||||
# =========================================================================
|
||||
|
||||
cleanup() {
|
||||
# Clean up temporary files when the script exits
|
||||
rm -rf "${TEMP_DIR}" 2>/dev/null
|
||||
}
|
||||
|
||||
trap cleanup EXIT
|
||||
|
||||
mkdir -p "${TEMP_DIR}"
|
||||
|
||||
print_header() {
|
||||
echo -e "\n${BOLD}Date : ${RESET}${CYAN}$(date -u '+%Y-%m-%d %H:%M:%S') UTC${RESET}"
|
||||
echo -e "${BOLD}User : ${RESET}${MAGENTA}$(whoami)${RESET}"
|
||||
echo -e "${BOLD}Branch : ${RESET}${GREEN}$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")${RESET}"
|
||||
echo -e "${BOLD}Directory : ${RESET}${BLUE}$(pwd)${RESET}"
|
||||
|
||||
if [ "$NODE_ENV" != "production" ]; then
|
||||
echo -e "${BOLD}Mode : ${RESET}${YELLOW}${NODE_ENV}${RESET}"
|
||||
fi
|
||||
|
||||
if [ "$WATCH_MODE" = true ]; then
|
||||
echo -e "${BOLD}Watch : ${RESET}${CYAN}enabled${RESET}"
|
||||
fi
|
||||
|
||||
if [ "$THEME_ONLY" = true ]; then
|
||||
echo -e "${BOLD}Scope : ${RESET}${MAGENTA}themes only${RESET}"
|
||||
elif [ "$MODULE_ONLY" = true ]; then
|
||||
echo -e "${BOLD}Scope : ${RESET}${MAGENTA}modules only${RESET}"
|
||||
fi
|
||||
|
||||
echo
|
||||
}
|
||||
|
||||
print_section() {
|
||||
echo -e "\n${BOLD}${CYAN}┌─ $1 ${2:-}${RESET}"
|
||||
}
|
||||
|
||||
success_msg() {
|
||||
echo -e "${GREEN}${CHECK} $*${RESET}"
|
||||
}
|
||||
|
||||
error_msg() {
|
||||
echo -e "${RED}${ERROR} $*${RESET}"
|
||||
}
|
||||
|
||||
warning_msg() {
|
||||
echo -e "${YELLOW}${WARNING} $*${RESET}"
|
||||
}
|
||||
|
||||
info_msg() {
|
||||
echo -e "${BLUE}${HOURGLASS} $*${RESET}"
|
||||
}
|
||||
|
||||
print_usage() {
|
||||
echo -e "${BOLD}Usage:${RESET} $0 [options]"
|
||||
echo
|
||||
echo -e "${BOLD}Options:${RESET}"
|
||||
echo -e " ${GREEN}-h, --help${RESET} Show this help message"
|
||||
echo -e " ${GREEN}-v, --verbose${RESET} Display detailed build output"
|
||||
echo -e " ${GREEN}-w, --watch${RESET} Run in watch mode"
|
||||
echo -e " ${GREEN}-d, --development${RESET} Build in development mode (unminified)"
|
||||
echo -e " ${GREEN}-t, --themes-only${RESET} Build only themes"
|
||||
echo -e " ${GREEN}-m, --modules-only${RESET} Build only modules (core and plugins)"
|
||||
echo -e " ${GREEN}-a, --analyze${RESET} Show detailed size analysis in table format"
|
||||
echo -e " ${GREEN}-D, --deep-analyze${RESET} Perform deep analysis of files (checksums, content inspection)"
|
||||
echo -e " ${GREEN}--skip-clear${RESET} Skip clearing output directories"
|
||||
echo
|
||||
}
|
||||
|
||||
parse_args() {
|
||||
while [ "$#" -gt 0 ]; do
|
||||
case "$1" in
|
||||
-h|--help)
|
||||
print_usage
|
||||
exit 0
|
||||
;;
|
||||
-v|--verbose)
|
||||
VERBOSE=true
|
||||
;;
|
||||
-w|--watch)
|
||||
WATCH_MODE=true
|
||||
NODE_ENV="development"
|
||||
;;
|
||||
-d|--development)
|
||||
NODE_ENV="development"
|
||||
;;
|
||||
-t|--themes-only)
|
||||
THEME_ONLY=true
|
||||
;;
|
||||
-m|--modules-only)
|
||||
MODULE_ONLY=true
|
||||
;;
|
||||
-a|--analyze)
|
||||
ANALYZE=true
|
||||
;;
|
||||
-D|--deep-analyze)
|
||||
ANALYZE=true
|
||||
DEEP_ANALYZE=true
|
||||
;;
|
||||
--skip-clear)
|
||||
SKIP_CLEAR=true
|
||||
;;
|
||||
*)
|
||||
warning_msg "Unknown option: $1"
|
||||
print_usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# Validate conflicting options
|
||||
if [ "$THEME_ONLY" = true ] && [ "$MODULE_ONLY" = true ]; then
|
||||
error_msg "Cannot specify both --themes-only and --modules-only"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Configure build mode
|
||||
if [ "$WATCH_MODE" = true ]; then
|
||||
ROLLUP_ARGS="-c -w"
|
||||
else
|
||||
ROLLUP_ARGS="-c"
|
||||
fi
|
||||
|
||||
# When analyzing, we turn off verbosity for rollup
|
||||
if [ "$ANALYZE" = true ]; then
|
||||
export FILESIZE_SILENT=true
|
||||
fi
|
||||
}
|
||||
|
||||
# =========================================================================
|
||||
# BUILD FUNCTIONS
|
||||
# =========================================================================
|
||||
|
||||
get_size_info() {
|
||||
local file="$1"
|
||||
# Get precise byte count for more accurate comparison
|
||||
local bytes=$(wc -c < "$file")
|
||||
local size=$(du -h "$file" | awk '{print $1}')
|
||||
local gzip=$(gzip -c "$file" | wc -c | numfmt --to=iec --format="%.1f")
|
||||
local brotli_size=$(brotli -c "$file" 2>/dev/null | wc -c | numfmt --to=iec --format="%.1f" || echo "N/A")
|
||||
|
||||
echo "$size|$gzip|$bytes|$brotli_size"
|
||||
}
|
||||
|
||||
get_file_hash() {
|
||||
local file="$1"
|
||||
if command -v sha256sum &> /dev/null; then
|
||||
sha256sum "$file" | awk '{print $1}'
|
||||
elif command -v shasum &> /dev/null; then
|
||||
shasum -a 256 "$file" | awk '{print $1}'
|
||||
else
|
||||
echo "HASH_UNAVAILABLE"
|
||||
fi
|
||||
}
|
||||
|
||||
analyze_file_content() {
|
||||
local file="$1"
|
||||
local filename=$(basename "$file")
|
||||
local dir="${TEMP_DIR}/analysis/$(dirname "$file" | sed 's/\//_/g')"
|
||||
mkdir -p "$dir"
|
||||
|
||||
# Get first 10 lines for a quick look
|
||||
head -n 10 "$file" > "${dir}/${filename}.head"
|
||||
|
||||
# Get hash for exact comparison
|
||||
local hash=$(get_file_hash "$file")
|
||||
echo "$hash" > "${dir}/${filename}.hash"
|
||||
|
||||
# For CSS/JS, try to determine if it's minified
|
||||
if [[ "$file" == *.css || "$file" == *.js ]]; then
|
||||
# Count semicolons to help identify if minified
|
||||
local semicolons=$(grep -o ";" "$file" | wc -l)
|
||||
# Count newlines
|
||||
local newlines=$(grep -c $'\n' "$file")
|
||||
|
||||
# Simple heuristic: if few newlines relative to semicolons, likely minified
|
||||
if [ "$newlines" -lt 10 ] || [ "$semicolons" -gt "$((newlines * 5))" ]; then
|
||||
echo "MINIFIED:YES semicolons:$semicolons newlines:$newlines" > "${dir}/${filename}.analysis"
|
||||
else
|
||||
echo "MINIFIED:NO semicolons:$semicolons newlines:$newlines" > "${dir}/${filename}.analysis"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "$hash"
|
||||
}
|
||||
|
||||
collect_build_statistics() {
|
||||
local modules_count=0
|
||||
local themes_count=0
|
||||
declare -a theme_names=()
|
||||
local unique_css_hashes=0
|
||||
local unique_js_hashes=0
|
||||
declare -A css_hashes=()
|
||||
declare -A js_hashes=()
|
||||
|
||||
# Create temporary directory for data
|
||||
mkdir -p "${TEMP_DIR}/modules"
|
||||
mkdir -p "${TEMP_DIR}/themes"
|
||||
mkdir -p "${TEMP_DIR}/analysis"
|
||||
|
||||
echo "DEBUG: Looking for modules and themes..." >> "${BUILD_LOG}"
|
||||
|
||||
# Check for core flasher module first
|
||||
if [ -f "${PRIME_PATH}/dist/flasher.min.js" ]; then
|
||||
local size_info=$(get_size_info "${PRIME_PATH}/dist/flasher.min.js")
|
||||
local hash="N/A"
|
||||
if [ "$DEEP_ANALYZE" = true ]; then
|
||||
hash=$(analyze_file_content "${PRIME_PATH}/dist/flasher.min.js")
|
||||
js_hashes["$hash"]=1
|
||||
((unique_js_hashes++))
|
||||
fi
|
||||
echo "flasher:$size_info:$hash" >> "${TEMP_DIR}/modules/data"
|
||||
((modules_count++))
|
||||
fi
|
||||
|
||||
# Collect module statistics - FIXED to avoid subshell issue
|
||||
# Store filenames to process in a temporary file
|
||||
find ${SRC_DIR}/*/Prime/Resources/dist -name "*.min.js" | grep -v themes > "${TEMP_DIR}/module_files.txt" 2>/dev/null
|
||||
|
||||
# Process each module file
|
||||
while IFS= read -r file; do
|
||||
local module=$(basename "$file" .min.js)
|
||||
local size_info=$(get_size_info "$file")
|
||||
local hash="N/A"
|
||||
if [ "$DEEP_ANALYZE" = true ]; then
|
||||
hash=$(analyze_file_content "$file")
|
||||
js_hashes["$hash"]=1
|
||||
((unique_js_hashes++))
|
||||
fi
|
||||
echo "$module:$size_info:$hash" >> "${TEMP_DIR}/modules/data"
|
||||
((modules_count++))
|
||||
echo "DEBUG: Found module: $module in $file (${size_info})" >> "${BUILD_LOG}"
|
||||
done < "${TEMP_DIR}/module_files.txt"
|
||||
|
||||
# Collect theme statistics - FIXED to avoid subshell issue
|
||||
if [ -d "${PRIME_PATH}/dist/themes" ]; then
|
||||
# Store theme files in a temporary file
|
||||
find ${PRIME_PATH}/dist/themes -name "*.min.js" > "${TEMP_DIR}/theme_files.txt" 2>/dev/null
|
||||
|
||||
# Process each theme file
|
||||
while IFS= read -r file; do
|
||||
local theme=$(basename "$(dirname "$file")")
|
||||
local size_info=$(get_size_info "$file")
|
||||
local js_hash="N/A"
|
||||
local css_hash="N/A"
|
||||
|
||||
# Also get the CSS file size and analyze it
|
||||
local css_file="${PRIME_PATH}/dist/themes/${theme}/${theme}.min.css"
|
||||
local css_size_info="N/A"
|
||||
if [ -f "$css_file" ]; then
|
||||
css_size_info=$(get_size_info "$css_file")
|
||||
|
||||
if [ "$DEEP_ANALYZE" = true ]; then
|
||||
css_hash=$(analyze_file_content "$css_file")
|
||||
if [ -z "${css_hashes[$css_hash]}" ]; then
|
||||
css_hashes["$css_hash"]=1
|
||||
((unique_css_hashes++))
|
||||
else
|
||||
css_hashes["$css_hash"]=$((css_hashes["$css_hash"] + 1))
|
||||
fi
|
||||
|
||||
js_hash=$(analyze_file_content "$file")
|
||||
if [ -z "${js_hashes[$js_hash]}" ]; then
|
||||
js_hashes["$js_hash"]=1
|
||||
else
|
||||
js_hashes["$js_hash"]=$((js_hashes["$js_hash"] + 1))
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "DEBUG: Theme $theme JS: $size_info, CSS: $css_size_info" >> "${BUILD_LOG}"
|
||||
else
|
||||
echo "DEBUG: No CSS file found for theme $theme" >> "${BUILD_LOG}"
|
||||
fi
|
||||
|
||||
echo "$theme:$size_info:$js_hash:$css_size_info:$css_hash" >> "${TEMP_DIR}/themes/data"
|
||||
theme_names+=("$theme")
|
||||
((themes_count++))
|
||||
done < "${TEMP_DIR}/theme_files.txt"
|
||||
|
||||
# Sort theme names alphabetically
|
||||
if [ ${#theme_names[@]} -gt 0 ]; then
|
||||
printf "%s\n" "${theme_names[@]}" | sort > "${TEMP_DIR}/theme_names"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Store counts for summary
|
||||
echo "$modules_count" > "${TEMP_DIR}/modules_count"
|
||||
echo "$themes_count" > "${TEMP_DIR}/themes_count"
|
||||
echo "$unique_js_hashes" > "${TEMP_DIR}/unique_js_hashes"
|
||||
echo "$unique_css_hashes" > "${TEMP_DIR}/unique_css_hashes"
|
||||
|
||||
# Write hash statistics if deep analysis was enabled
|
||||
if [ "$DEEP_ANALYZE" = true ]; then
|
||||
echo "JS Hash Distribution:" > "${TEMP_DIR}/hash_stats.txt"
|
||||
for hash in "${!js_hashes[@]}"; do
|
||||
echo " $hash: ${js_hashes[$hash]} files" >> "${TEMP_DIR}/hash_stats.txt"
|
||||
done
|
||||
|
||||
echo -e "\nCSS Hash Distribution:" >> "${TEMP_DIR}/hash_stats.txt"
|
||||
for hash in "${!css_hashes[@]}"; do
|
||||
echo " $hash: ${css_hashes[$hash]} files" >> "${TEMP_DIR}/hash_stats.txt"
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
run_build() {
|
||||
print_section "Starting Build Process" "${HAMMER}"
|
||||
|
||||
info_msg "Environment: ${NODE_ENV}"
|
||||
info_msg "Building PHP-Flasher assets..."
|
||||
|
||||
# Set environment variables
|
||||
export NODE_ENV="$NODE_ENV"
|
||||
export ANALYZE="$ANALYZE"
|
||||
export DEEP_ANALYZE="$DEEP_ANALYZE"
|
||||
|
||||
# Determine which parts to build based on flags
|
||||
local rollup_args="$ROLLUP_ARGS"
|
||||
if [ "$THEME_ONLY" = true ]; then
|
||||
info_msg "Building themes only"
|
||||
# Here we'd need to extend rollup to support theme-only builds
|
||||
# For now, we'll complete the full build
|
||||
elif [ "$MODULE_ONLY" = true ]; then
|
||||
info_msg "Building modules only"
|
||||
# Similarly, we'd need to extend rollup
|
||||
fi
|
||||
|
||||
# Execute rollup with appropriate flags
|
||||
if [ "$VERBOSE" = true ]; then
|
||||
if npx rollup $rollup_args; then
|
||||
success_msg "Build process completed"
|
||||
return 0
|
||||
else
|
||||
error_msg "Build process failed"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
# Capture output for non-verbose mode
|
||||
if npx rollup $rollup_args > "$BUILD_LOG" 2>&1; then
|
||||
success_msg "Build process completed"
|
||||
return 0
|
||||
else
|
||||
error_msg "Build process failed"
|
||||
cat "$BUILD_LOG"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# =========================================================================
|
||||
# REPORTING FUNCTIONS
|
||||
# =========================================================================
|
||||
|
||||
print_size_table() {
|
||||
local title="$1"
|
||||
local data_file="$2"
|
||||
local max_name_len=20
|
||||
|
||||
if [ ! -f "$data_file" ] || [ ! -s "$data_file" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
echo -e "\n${BOLD}${WHITE}${title}${RESET}\n"
|
||||
|
||||
# Print table header with or without hashes based on deep analysis
|
||||
if [ "$DEEP_ANALYZE" = true ]; then
|
||||
printf "${BOLD}%-${max_name_len}s %-10s %-10s %-10s %-10s${RESET}\n" "Component" "Size" "Gzip" "Bytes" "Hash"
|
||||
else
|
||||
printf "${BOLD}%-${max_name_len}s %-10s %-10s %-10s${RESET}\n" "Component" "Size" "Gzip" "Bytes"
|
||||
fi
|
||||
|
||||
echo -e "${DIM}$(printf '%.0s─' {1..70})${RESET}"
|
||||
|
||||
# Print table rows
|
||||
while IFS=: read -r line; do
|
||||
# Split the line into fields
|
||||
local fields=()
|
||||
while IFS=: read -ra parts; do
|
||||
fields=("${parts[@]}")
|
||||
done <<< "$line"
|
||||
|
||||
local name="${fields[0]}"
|
||||
local size_data="${fields[1]}"
|
||||
local hash="N/A"
|
||||
if [ "${#fields[@]}" -gt 2 ]; then
|
||||
hash="${fields[2]}"
|
||||
fi
|
||||
|
||||
IFS='|' read -r size gzip bytes brotli <<< "$size_data"
|
||||
|
||||
if [ "$DEEP_ANALYZE" = true ]; then
|
||||
printf "%-${max_name_len}s ${GREEN}%-10s${RESET} ${BLUE}%-10s${RESET} ${YELLOW}%-10s${RESET} ${DIM}%.8s${RESET}\n" \
|
||||
"$name" "$size" "$gzip" "$bytes" "$hash"
|
||||
else
|
||||
printf "%-${max_name_len}s ${GREEN}%-10s${RESET} ${BLUE}%-10s${RESET} ${YELLOW}%-10s${RESET}\n" \
|
||||
"$name" "$size" "$gzip" "$bytes"
|
||||
fi
|
||||
done < "$data_file"
|
||||
}
|
||||
|
||||
print_theme_table() {
|
||||
local data_file="$1"
|
||||
local max_name_len=15
|
||||
|
||||
if [ ! -f "$data_file" ] || [ ! -s "$data_file" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
echo -e "\n${BOLD}${WHITE}Theme Sizes${RESET}\n"
|
||||
|
||||
# Print table header
|
||||
printf "${BOLD}%-${max_name_len}s %-10s %-10s %-10s %-10s${RESET}\n" "Theme" "JS Size" "CSS Size" "JS Bytes" "CSS Bytes"
|
||||
echo -e "${DIM}$(printf '%.0s─' {1..70})${RESET}"
|
||||
|
||||
# Print table rows
|
||||
while IFS=: read -r line; do
|
||||
# Split the line into fields
|
||||
local fields=()
|
||||
while IFS=: read -ra parts; do
|
||||
fields=("${parts[@]}")
|
||||
done <<< "$line"
|
||||
|
||||
local name="${fields[0]}"
|
||||
local js_size_data="${fields[1]}"
|
||||
local js_hash="N/A"
|
||||
local css_size_data="N/A"
|
||||
local css_hash="N/A"
|
||||
|
||||
if [ "${#fields[@]}" -gt 2 ]; then
|
||||
js_hash="${fields[2]}"
|
||||
fi
|
||||
|
||||
if [ "${#fields[@]}" -gt 3 ]; then
|
||||
css_size_data="${fields[3]}"
|
||||
fi
|
||||
|
||||
if [ "${#fields[@]}" -gt 4 ]; then
|
||||
css_hash="${fields[4]}"
|
||||
fi
|
||||
|
||||
IFS='|' read -r js_size js_gzip js_bytes js_brotli <<< "$js_size_data"
|
||||
|
||||
local css_size="N/A"
|
||||
local css_bytes="N/A"
|
||||
|
||||
if [ "$css_size_data" != "N/A" ]; then
|
||||
IFS='|' read -r css_size css_gzip css_bytes css_brotli <<< "$css_size_data"
|
||||
fi
|
||||
|
||||
printf "%-${max_name_len}s ${GREEN}%-10s${RESET} ${MAGENTA}%-10s${RESET} ${YELLOW}%-10s${RESET} ${BLUE}%-10s${RESET}\n" \
|
||||
"$name" "$js_size" "$css_size" "$js_bytes" "$css_bytes"
|
||||
done < "$data_file"
|
||||
}
|
||||
|
||||
print_theme_grid() {
|
||||
local theme_names_file="$1"
|
||||
if [ ! -f "$theme_names_file" ] || [ ! -s "$theme_names_file" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
echo -e "\n${BOLD}${MAGENTA}${PALETTE} Themes:${RESET}"
|
||||
|
||||
# Define grid parameters
|
||||
local columns=3
|
||||
local max_width=15
|
||||
local count=0
|
||||
|
||||
# Print themes in a grid
|
||||
while read -r theme; do
|
||||
if [ $((count % columns)) -eq 0 ]; then
|
||||
echo -ne " "
|
||||
fi
|
||||
|
||||
printf "• %-${max_width}s" "$theme"
|
||||
count=$((count + 1))
|
||||
|
||||
if [ $((count % columns)) -eq 0 ]; then
|
||||
echo
|
||||
fi
|
||||
done < "$theme_names_file"
|
||||
|
||||
# Add a newline if the last row wasn't complete
|
||||
if [ $((count % columns)) -ne 0 ]; then
|
||||
echo
|
||||
fi
|
||||
}
|
||||
|
||||
print_deep_analysis() {
|
||||
if [ ! -d "${TEMP_DIR}/analysis" ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
local unique_js=0
|
||||
local unique_css=0
|
||||
|
||||
if [ -f "${TEMP_DIR}/unique_js_hashes" ]; then
|
||||
unique_js=$(cat "${TEMP_DIR}/unique_js_hashes")
|
||||
fi
|
||||
|
||||
if [ -f "${TEMP_DIR}/unique_css_hashes" ]; then
|
||||
unique_css=$(cat "${TEMP_DIR}/unique_css_hashes")
|
||||
fi
|
||||
|
||||
echo -e "\n${BOLD}${WHITE}Deep File Analysis${RESET}"
|
||||
echo -e "${DIM}$(printf '%.0s─' {1..50})${RESET}"
|
||||
|
||||
echo -e "Unique JavaScript files: ${YELLOW}${unique_js}${RESET}"
|
||||
echo -e "Unique CSS files: ${MAGENTA}${unique_css}${RESET}"
|
||||
|
||||
if [ -f "${TEMP_DIR}/hash_stats.txt" ]; then
|
||||
echo -e "\n${BOLD}Hash Distribution:${RESET}"
|
||||
local top_5=$(head -n 10 "${TEMP_DIR}/hash_stats.txt")
|
||||
echo -e "${DIM}$top_5${RESET}"
|
||||
echo -e "${DIM}(See ${TEMP_DIR}/hash_stats.txt for full details)${RESET}"
|
||||
fi
|
||||
}
|
||||
|
||||
print_summary() {
|
||||
local success=$1
|
||||
local duration=$2
|
||||
|
||||
# Read statistics
|
||||
local modules_count=0
|
||||
local themes_count=0
|
||||
|
||||
if [ -f "${TEMP_DIR}/modules_count" ]; then
|
||||
modules_count=$(cat "${TEMP_DIR}/modules_count")
|
||||
fi
|
||||
|
||||
if [ -f "${TEMP_DIR}/themes_count" ]; then
|
||||
themes_count=$(cat "${TEMP_DIR}/themes_count")
|
||||
fi
|
||||
|
||||
# Print summary header
|
||||
echo -e "\n${BOLD}${PACKAGE} Build Summary${RESET}"
|
||||
echo -e "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
# Print statistics
|
||||
if [ "$MODULE_ONLY" = false ]; then
|
||||
echo -e "${CHECK} Modules/Plugins: ${BOLD}${CYAN}${modules_count}${RESET}"
|
||||
fi
|
||||
|
||||
if [ "$THEME_ONLY" = false ]; then
|
||||
echo -e "${CHECK} Themes: ${BOLD}${MAGENTA}${themes_count}${RESET}"
|
||||
fi
|
||||
|
||||
echo -e "${CHECK} Build completed in ${BOLD}${YELLOW}${duration}s${RESET}"
|
||||
|
||||
# Print theme names if available
|
||||
if [ -f "${TEMP_DIR}/theme_names" ]; then
|
||||
print_theme_grid "${TEMP_DIR}/theme_names"
|
||||
fi
|
||||
|
||||
# Show size analysis if requested
|
||||
if [ "$ANALYZE" = true ]; then
|
||||
echo -e "\n${BOLD}${CHART} Size Analysis:${RESET}"
|
||||
print_size_table "Module Sizes" "${TEMP_DIR}/modules/data"
|
||||
|
||||
if [ "$DEEP_ANALYZE" = true ]; then
|
||||
print_theme_table "${TEMP_DIR}/themes/data"
|
||||
print_deep_analysis
|
||||
else
|
||||
print_size_table "Theme Sizes" "${TEMP_DIR}/themes/data"
|
||||
fi
|
||||
|
||||
# Add option to view detailed logs
|
||||
echo -e "\nFor detailed build info, run: ${CYAN}cat $BUILD_LOG${RESET}"
|
||||
echo -e "Temporary files at: ${CYAN}${TEMP_DIR}${RESET}"
|
||||
fi
|
||||
}
|
||||
|
||||
# =========================================================================
|
||||
# MAIN EXECUTION
|
||||
# =========================================================================
|
||||
|
||||
main() {
|
||||
local start_time=$(date +%s)
|
||||
local build_success=true
|
||||
|
||||
# Parse command-line arguments
|
||||
parse_args "$@"
|
||||
|
||||
# Show header
|
||||
print_header
|
||||
|
||||
# Run the build process
|
||||
run_build || build_success=false
|
||||
|
||||
# Only collect statistics if build was successful and not in watch mode
|
||||
if [ "$WATCH_MODE" = false ] && [ "$build_success" = true ]; then
|
||||
if [ "$ANALYZE" = true ] || [ ! -t 1 ]; then
|
||||
print_section "Analyzing Build Output" "${CHART}"
|
||||
fi
|
||||
collect_build_statistics
|
||||
fi
|
||||
|
||||
# Print summary (unless in watch mode)
|
||||
if [ "$WATCH_MODE" = false ]; then
|
||||
local end_time=$(date +%s)
|
||||
local duration=$((end_time - start_time))
|
||||
|
||||
print_summary "$build_success" "$duration"
|
||||
fi
|
||||
|
||||
# Exit with appropriate code
|
||||
[ "$build_success" = true ] && exit 0 || exit 1
|
||||
}
|
||||
|
||||
# Execute main function with all arguments
|
||||
main "$@"
|
||||
@@ -0,0 +1,189 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
set -o pipefail
|
||||
|
||||
# Colors and styles
|
||||
readonly RESET='\033[0m'
|
||||
readonly BOLD='\033[1m'
|
||||
readonly BLUE='\033[34m'
|
||||
readonly GREEN='\033[32m'
|
||||
readonly RED='\033[31m'
|
||||
readonly YELLOW='\033[33m'
|
||||
|
||||
# Emojis
|
||||
readonly ROCKET="🚀"
|
||||
readonly UPDATE="🔄"
|
||||
readonly PACKAGE="📦"
|
||||
readonly SUCCESS="✨"
|
||||
readonly ERROR="❌"
|
||||
readonly WARNING="⚠️"
|
||||
readonly CHECK="✓"
|
||||
|
||||
# Header
|
||||
print_header() {
|
||||
echo -e "\n${BOLD}${BLUE}╭──────────────────────────────────────────╮${RESET}"
|
||||
echo -e "${BOLD}${BLUE}│ ${ROCKET} PHP-Flasher Version ${ROCKET} │${RESET}"
|
||||
echo -e "${BOLD}${BLUE}╰──────────────────────────────────────────╯${RESET}\n"
|
||||
echo -e " Date : $(date -u '+%Y-%m-%d %H:%M:%S') UTC"
|
||||
echo -e " User : $(whoami)"
|
||||
echo -e " Directory: $(pwd)\n"
|
||||
}
|
||||
|
||||
# Version validation
|
||||
validate_version() {
|
||||
local version=$1
|
||||
if [[ ! $version =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||
echo -e "\n${RED}${ERROR} Invalid version format: $version${RESET}"
|
||||
echo -e " Version must be in format X.Y.Z (e.g., 2.1.6)\n"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Get current version from Flasher class
|
||||
get_current_version() {
|
||||
local file="src/Prime/Flasher.php"
|
||||
if [ -f "$file" ]; then
|
||||
local version=$(grep -o "const VERSION = '[0-9]\+\.[0-9]\+\.[0-9]\+'" "$file" | grep -o "[0-9]\+\.[0-9]\+\.[0-9]\+")
|
||||
echo "$version"
|
||||
else
|
||||
echo -e "${RED}${ERROR} Flasher.php not found in src/Prime/Flasher.php${RESET}"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Update composer.json file
|
||||
update_composer_file() {
|
||||
local file=$1
|
||||
local current_version=$2
|
||||
local new_version=$3
|
||||
|
||||
# Create a temporary file
|
||||
local tmp_file="${file}.tmp"
|
||||
|
||||
# Use jq with 4-space indentation
|
||||
if command -v jq >/dev/null 2>&1; then
|
||||
jq --indent 4 --arg cv "^${current_version}" --arg nv "^${new_version}" '
|
||||
walk(
|
||||
if type == "object" and has("require") then
|
||||
.require |= with_entries(
|
||||
if .key | startswith("php-flasher/") then
|
||||
.value = $nv
|
||||
else
|
||||
.
|
||||
end
|
||||
)
|
||||
else
|
||||
.
|
||||
end
|
||||
)
|
||||
' "$file" > "$tmp_file"
|
||||
else
|
||||
# Fallback to sed for simple replacement
|
||||
sed -E "s/\"php-flasher\/[^\"]+\": \"\\^${current_version}\"/\"\\0\": \"^${new_version}\"/" "$file" > "$tmp_file"
|
||||
fi
|
||||
|
||||
# Check if the temporary file exists and has content
|
||||
if [ -s "$tmp_file" ]; then
|
||||
mv "$tmp_file" "$file"
|
||||
echo " ${CHECK} Updated $file"
|
||||
else
|
||||
echo " ${WARNING} Failed to update $file"
|
||||
rm -f "$tmp_file"
|
||||
fi
|
||||
}
|
||||
|
||||
# Update package.json file
|
||||
update_package_file() {
|
||||
local file=$1
|
||||
local current_version=$2
|
||||
local new_version=$3
|
||||
|
||||
# Create a temporary file
|
||||
local tmp_file="${file}.tmp"
|
||||
|
||||
# Use jq with 4-space indentation
|
||||
if command -v jq >/dev/null 2>&1; then
|
||||
jq --indent 4 --arg cv "^${current_version}" --arg nv "^${new_version}" --arg v "${new_version}" '
|
||||
.version = $v |
|
||||
if has("peerDependencies") then
|
||||
.peerDependencies |= with_entries(
|
||||
if .key | startswith("@flasher/") then
|
||||
.value = $nv
|
||||
else
|
||||
.
|
||||
end
|
||||
)
|
||||
else
|
||||
.
|
||||
end |
|
||||
if has("dependencies") then
|
||||
.dependencies |= with_entries(
|
||||
if .key | startswith("@flasher/") then
|
||||
.value = $nv
|
||||
else
|
||||
.
|
||||
end
|
||||
)
|
||||
else
|
||||
.
|
||||
end
|
||||
' "$file" > "$tmp_file"
|
||||
else
|
||||
# Fallback to sed for simple replacement
|
||||
sed -E -e "s/\"version\": \"${current_version}\"/\"version\": \"${new_version}\"/" \
|
||||
-e "s/\"@flasher\/[^\"]+\": \"\\^${current_version}\"/\"\\0\": \"^${new_version}\"/" \
|
||||
"$file" > "$tmp_file"
|
||||
fi
|
||||
|
||||
# Check if the temporary file exists and has content
|
||||
if [ -s "$tmp_file" ]; then
|
||||
mv "$tmp_file" "$file"
|
||||
echo " ${CHECK} Updated $file"
|
||||
else
|
||||
echo " ${WARNING} Failed to update $file"
|
||||
rm -f "$tmp_file"
|
||||
fi
|
||||
}
|
||||
|
||||
# Update version in files
|
||||
update_version() {
|
||||
local current_version=$1
|
||||
local new_version=$2
|
||||
|
||||
echo -e " ${UPDATE} Updating version numbers ($current_version → $new_version)\n"
|
||||
|
||||
# Update PHP class version
|
||||
echo -e " ${PACKAGE} Updating Flasher class version..."
|
||||
if [ -f "src/Prime/Flasher.php" ]; then
|
||||
sed -i '' "s/const VERSION = '$current_version'/const VERSION = '$new_version'/" src/Prime/Flasher.php
|
||||
echo -e " ${CHECK} Updated src/Prime/Flasher.php"
|
||||
fi
|
||||
|
||||
# Update composer.json files in src directory
|
||||
echo -e "\n ${PACKAGE} Updating composer.json files..."
|
||||
find src -name "composer.json" -type f | while read -r file; do
|
||||
update_composer_file "$file" "$current_version" "$new_version"
|
||||
done
|
||||
|
||||
# Update package.json files in src directory
|
||||
echo -e "\n ${PACKAGE} Updating package.json files..."
|
||||
find src -name "package.json" -type f | while read -r file; do
|
||||
update_package_file "$file" "$current_version" "$new_version"
|
||||
done
|
||||
|
||||
echo -e "\n ${SUCCESS} Version bump complete!\n"
|
||||
}
|
||||
|
||||
# Main execution
|
||||
if [ -z "$1" ]; then
|
||||
echo -e "${RED}${ERROR} Version number is required${RESET}"
|
||||
echo -e "Usage: $0 <version>\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
print_header
|
||||
new_version=$1
|
||||
current_version=$(get_current_version)
|
||||
validate_version "$new_version"
|
||||
update_version "$current_version" "$new_version"
|
||||
@@ -1,50 +1,35 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
#!/bin/bash
|
||||
|
||||
$shared = realpath(__DIR__.'/../.shared');
|
||||
# Default to the current directory if no directory is provided
|
||||
dir=${1:-.}
|
||||
|
||||
$resources = array(
|
||||
$shared,
|
||||
__DIR__.'/../.github/FUNDING.yml',
|
||||
__DIR__.'/../README.md',
|
||||
__DIR__.'/../LICENSE',
|
||||
);
|
||||
# Optional: A list of file extensions to filter by, e.g., "txt md". Leave empty to include all files.
|
||||
extensions=($2)
|
||||
|
||||
$dirs = array(__DIR__.'/../packs', __DIR__.'/../src');
|
||||
# Temporary file to store results
|
||||
temp_file=$(mktemp)
|
||||
|
||||
$packages = array_reduce($dirs, function ($files, $dir) {
|
||||
return array_merge($files, glob("$dir/*/composer.json"), glob("$dir/*/*/composer.json"));
|
||||
}, array());
|
||||
|
||||
foreach ($packages as $package) {
|
||||
$package = realpath(dirname($package));
|
||||
foreach ($resources as $resource) {
|
||||
$resource = realpath($resource);
|
||||
$dest = $package.str_replace(realpath(__DIR__.'/../'), '', $resource);
|
||||
|
||||
if (!is_dir($resource) && file_exists($resource)) {
|
||||
copy($resource, $dest);
|
||||
continue;
|
||||
}
|
||||
|
||||
$files = new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator($resource, FilesystemIterator::SKIP_DOTS),
|
||||
RecursiveIteratorIterator::SELF_FIRST
|
||||
);
|
||||
|
||||
foreach ($files as $file) {
|
||||
$target = $resource === $shared
|
||||
? $package.str_replace($resource, '', $file->getPathname())
|
||||
: $dest .'/'. $file->getFilename();
|
||||
|
||||
if ($file->isDir()) {
|
||||
system('rm -rf -- ' . escapeshellarg($dest));
|
||||
@mkdir(dirname($target), 0777, true);
|
||||
continue;
|
||||
}
|
||||
|
||||
@mkdir(dirname($target), 0777, true);
|
||||
@copy($file->getPathname(), $target);
|
||||
}
|
||||
}
|
||||
# Function to print file details (now inline within find command)
|
||||
print_file_details() {
|
||||
echo "File Path: $1"
|
||||
echo "Contents:"
|
||||
cat "$1"
|
||||
echo
|
||||
}
|
||||
|
||||
# Finding and processing files
|
||||
if [ ${#extensions[@]} -eq 0 ]; then
|
||||
# If no extensions are specified, process all files
|
||||
find "$dir" -type f -exec bash -c 'echo "File Path: $1"; echo "Contents:"; cat "$1"; echo' bash {} \; >> "$temp_file"
|
||||
else
|
||||
# Process only files with specified extensions
|
||||
for ext in "${extensions[@]}"; do
|
||||
find "$dir" -type f -name "*.$ext" -exec bash -c 'echo "File Path: $1"; echo "Contents:"; cat "$1"; echo' bash {} \; >> "$temp_file"
|
||||
done
|
||||
fi
|
||||
|
||||
# Copy results to clipboard and remove the temporary file
|
||||
cat "$temp_file" | pbcopy
|
||||
rm "$temp_file"
|
||||
|
||||
echo "Results copied to clipboard."
|
||||
|
||||
Executable
+129
@@ -0,0 +1,129 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -o pipefail
|
||||
|
||||
# PHP binary to use (defaults to PHP 8.2)
|
||||
PHP_BINARY="${PHP_BINARY:-/opt/homebrew/opt/php@8.2/bin/php}"
|
||||
|
||||
# Colors and styles
|
||||
readonly RESET='\033[0m'
|
||||
readonly BOLD='\033[1m'
|
||||
readonly DIM='\033[2m'
|
||||
readonly BLUE='\033[34m'
|
||||
readonly GREEN='\033[32m'
|
||||
readonly RED='\033[31m'
|
||||
readonly YELLOW='\033[33m'
|
||||
readonly CYAN='\033[36m'
|
||||
readonly MAGENTA='\033[35m'
|
||||
|
||||
# Essential emojis
|
||||
readonly ROCKET="🚀"
|
||||
readonly CHECK="✓"
|
||||
readonly ERROR="❌"
|
||||
readonly WARNING="⚠️"
|
||||
readonly CHART="📊"
|
||||
readonly TEST_TUBE="🧪"
|
||||
readonly SPARKLES="✨"
|
||||
readonly GLOBE="🌐"
|
||||
|
||||
print_header() {
|
||||
echo -e "\n${BOLD}${BLUE}${ROCKET} PHP-Flasher Test Coverage ${ROCKET}${RESET}\n"
|
||||
echo -e "${BOLD}Date : ${RESET}${CYAN}$(date -u '+%Y-%m-%d %H:%M:%S') UTC${RESET}"
|
||||
echo -e "${BOLD}Directory : ${RESET}${BLUE}$(pwd)${RESET}\n"
|
||||
}
|
||||
|
||||
cleanup_coverage() {
|
||||
echo -e "${BOLD}${DIM}Cleaning up old coverage reports...${RESET}"
|
||||
rm -rf coverage/phpunit coverage/vitest
|
||||
mkdir -p coverage/phpunit coverage/vitest
|
||||
echo -e "${CHECK} ${GREEN}Cleanup complete${RESET}\n"
|
||||
}
|
||||
|
||||
run_phpunit_coverage() {
|
||||
echo -e "${BOLD}${TEST_TUBE} Running PHPUnit with Coverage${RESET}"
|
||||
|
||||
if $PHP_BINARY vendor/bin/phpunit --coverage-html coverage/phpunit/html --coverage-text=coverage/phpunit/report.txt; then
|
||||
echo -e "${CHECK} ${GREEN}PHPUnit coverage generated${RESET}"
|
||||
echo -e " ${DIM}HTML Report: coverage/phpunit/html/index.html${RESET}\n"
|
||||
return 0
|
||||
else
|
||||
echo -e "${WARNING} ${YELLOW}PHPUnit coverage generation failed${RESET}\n"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
run_vitest_coverage() {
|
||||
echo -e "${BOLD}${TEST_TUBE} Running Vitest with Coverage${RESET}"
|
||||
|
||||
if npm run test:coverage; then
|
||||
echo -e "${CHECK} ${GREEN}Vitest coverage generated${RESET}"
|
||||
echo -e " ${DIM}HTML Report: coverage/vitest/index.html${RESET}\n"
|
||||
return 0
|
||||
else
|
||||
echo -e "${WARNING} ${YELLOW}Vitest coverage generation failed${RESET}\n"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
print_summary() {
|
||||
echo -e "${BOLD}${CYAN}${CHART} Coverage Reports Summary${RESET}\n"
|
||||
|
||||
echo -e "${BOLD}PHPUnit Coverage:${RESET}"
|
||||
if [ -f "coverage/phpunit/html/index.html" ]; then
|
||||
echo -e " ${GREEN}${CHECK} HTML: ${RESET}coverage/phpunit/html/index.html"
|
||||
if [ -f "coverage/phpunit/report.txt" ]; then
|
||||
echo -e " ${GREEN}${CHECK} Text: ${RESET}coverage/phpunit/report.txt"
|
||||
fi
|
||||
else
|
||||
echo -e " ${RED}${ERROR} No coverage report generated${RESET}"
|
||||
fi
|
||||
|
||||
echo -e "\n${BOLD}Vitest Coverage:${RESET}"
|
||||
if [ -f "coverage/vitest/index.html" ]; then
|
||||
echo -e " ${GREEN}${CHECK} HTML: ${RESET}coverage/vitest/index.html"
|
||||
if [ -f "coverage/vitest/coverage-final.json" ]; then
|
||||
echo -e " ${GREEN}${CHECK} JSON: ${RESET}coverage/vitest/coverage-final.json"
|
||||
fi
|
||||
else
|
||||
echo -e " ${RED}${ERROR} No coverage report generated${RESET}"
|
||||
fi
|
||||
|
||||
echo -e "\n${BOLD}${GLOBE} Open Reports:${RESET}"
|
||||
echo -e " ${CYAN}npm run coverage:open${RESET}"
|
||||
echo -e " ${DIM}Or manually open the HTML files in your browser${RESET}\n"
|
||||
}
|
||||
|
||||
open_reports() {
|
||||
if [ "$1" == "--open" ] || [ "$1" == "-o" ]; then
|
||||
echo -e "${BOLD}${GLOBE} Opening coverage reports...${RESET}\n"
|
||||
|
||||
if [ -f "coverage/phpunit/html/index.html" ]; then
|
||||
open coverage/phpunit/html/index.html 2>/dev/null || xdg-open coverage/phpunit/html/index.html 2>/dev/null
|
||||
fi
|
||||
|
||||
if [ -f "coverage/vitest/index.html" ]; then
|
||||
open coverage/vitest/index.html 2>/dev/null || xdg-open coverage/vitest/index.html 2>/dev/null
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
main() {
|
||||
local start_time=$(date +%s)
|
||||
|
||||
print_header
|
||||
cleanup_coverage
|
||||
run_phpunit_coverage
|
||||
run_vitest_coverage
|
||||
|
||||
local end_time=$(date +%s)
|
||||
local duration=$((end_time - start_time))
|
||||
|
||||
print_summary
|
||||
|
||||
echo -e "${SPARKLES} ${BOLD}Coverage Complete${RESET}"
|
||||
echo -e "Duration: ${YELLOW}${duration}s${RESET}\n"
|
||||
|
||||
open_reports "$1"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
@@ -1,35 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Default to the current directory if no directory is provided
|
||||
dir=${1:-.}
|
||||
|
||||
# Optional: A list of file extensions to filter by, e.g., "txt md". Leave empty to include all files.
|
||||
extensions=($2)
|
||||
|
||||
# Temporary file to store results
|
||||
temp_file=$(mktemp)
|
||||
|
||||
# Function to print file details (now inline within find command)
|
||||
print_file_details() {
|
||||
echo "File Path: $1"
|
||||
echo "Contents:"
|
||||
cat "$1"
|
||||
echo
|
||||
}
|
||||
|
||||
# Finding and processing files
|
||||
if [ ${#extensions[@]} -eq 0 ]; then
|
||||
# If no extensions are specified, process all files
|
||||
find "$dir" -type f -exec bash -c 'echo "File Path: $1"; echo "Contents:"; cat "$1"; echo' bash {} \; >> "$temp_file"
|
||||
else
|
||||
# Process only files with specified extensions
|
||||
for ext in "${extensions[@]}"; do
|
||||
find "$dir" -type f -name "*.$ext" -exec bash -c 'echo "File Path: $1"; echo "Contents:"; cat "$1"; echo' bash {} \; >> "$temp_file"
|
||||
done
|
||||
fi
|
||||
|
||||
# Copy results to clipboard and remove the temporary file
|
||||
cat "$temp_file" | pbcopy
|
||||
rm "$temp_file"
|
||||
|
||||
echo "Results copied to clipboard."
|
||||
@@ -0,0 +1,101 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -o pipefail
|
||||
|
||||
# Colors and styles
|
||||
readonly RESET='\033[0m'
|
||||
readonly BOLD='\033[1m'
|
||||
readonly DIM='\033[2m'
|
||||
readonly UNDERLINE='\033[4m'
|
||||
readonly BLUE='\033[34m'
|
||||
readonly GREEN='\033[32m'
|
||||
readonly RED='\033[31m'
|
||||
readonly YELLOW='\033[33m'
|
||||
readonly CYAN='\033[36m'
|
||||
readonly MAGENTA='\033[35m'
|
||||
|
||||
# Essential emojis
|
||||
readonly ROCKET="🚀"
|
||||
readonly CHECK="✓"
|
||||
readonly ERROR="❌"
|
||||
readonly WARNING="⚠️"
|
||||
readonly BOOKS="📚"
|
||||
readonly HAMMER="🏗️"
|
||||
readonly SPARKLES="✨"
|
||||
|
||||
print_header() {
|
||||
echo -e "\n${BOLD}${BLUE}${ROCKET} PHP-Flasher Documentation Builder ${ROCKET}${RESET}\n"
|
||||
echo -e "${BOLD}Date : ${RESET}${CYAN}$(date -u '+%Y-%m-%d %H:%M:%S') UTC${RESET}"
|
||||
echo -e "${BOLD}User : ${RESET}${MAGENTA}yoeunes${RESET}"
|
||||
echo -e "${BOLD}Branch : ${RESET}${GREEN}$(git rev-parse --abbrev-ref HEAD)${RESET}"
|
||||
echo -e "${BOLD}Directory : ${RESET}${BLUE}$(pwd)${RESET}\n"
|
||||
}
|
||||
|
||||
install_dependencies() {
|
||||
echo -e "${BOLD}${BOOKS} Installing dependencies${RESET}"
|
||||
|
||||
if npm install --force; then
|
||||
echo -e "${CHECK} ${GREEN}Dependencies installed successfully${RESET}\n"
|
||||
return 0
|
||||
else
|
||||
echo -e "${WARNING} ${YELLOW}Dependency installation had issues${RESET}\n"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
build_documentation() {
|
||||
echo -e "${BOLD}${HAMMER} Building documentation${RESET}"
|
||||
|
||||
if npm run build; then
|
||||
echo -e "${CHECK} ${GREEN}Documentation built successfully${RESET}\n"
|
||||
return 0
|
||||
else
|
||||
echo -e "${ERROR} ${RED}Documentation build failed${RESET}\n"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
main() {
|
||||
local command=${1:-"build"}
|
||||
local start_time=$(date +%s)
|
||||
local success=true
|
||||
|
||||
# Change directory to docs/
|
||||
if [[ ! -d "docs/" ]]; then
|
||||
echo -e "${ERROR} ${RED}Documentation directory 'docs/' not found${RESET}\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd docs/
|
||||
|
||||
print_header
|
||||
echo -e "${BOLD}Command : ${RESET}${CYAN}${command}${RESET}\n"
|
||||
|
||||
case $command in
|
||||
"build")
|
||||
install_dependencies || success=false
|
||||
build_documentation || success=false
|
||||
;;
|
||||
*)
|
||||
echo -e "${ERROR} ${RED}Unknown command: ${command}${RESET}"
|
||||
echo -e "Available commands: build"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
local end_time=$(date +%s)
|
||||
local duration=$((end_time - start_time))
|
||||
|
||||
# Summary
|
||||
echo -e "${BOLD}${CYAN}Documentation ${command^} Summary${RESET}"
|
||||
if [ "$success" = true ]; then
|
||||
echo -e "${SPARKLES} ${GREEN}Documentation ${command} completed successfully${RESET}"
|
||||
else
|
||||
echo -e "${WARNING} ${YELLOW}Documentation ${command} completed with issues${RESET}"
|
||||
fi
|
||||
echo -e "Duration : ${YELLOW}${duration}s${RESET}\n"
|
||||
|
||||
[ "$success" = true ] && exit 0 || exit 1
|
||||
}
|
||||
|
||||
main "$@"
|
||||
@@ -0,0 +1,174 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -o pipefail
|
||||
|
||||
# PHP binary to use (defaults to PHP 8.2)
|
||||
PHP_BINARY="${PHP_BINARY:-/opt/homebrew/opt/php@8.2/bin/php}"
|
||||
|
||||
# Colors and styles
|
||||
readonly RESET='\033[0m'
|
||||
readonly BOLD='\033[1m'
|
||||
readonly DIM='\033[2m'
|
||||
readonly UNDERLINE='\033[4m'
|
||||
readonly BLUE='\033[34m'
|
||||
readonly GREEN='\033[32m'
|
||||
readonly RED='\033[31m'
|
||||
readonly YELLOW='\033[33m'
|
||||
readonly CYAN='\033[36m'
|
||||
readonly MAGENTA='\033[35m'
|
||||
|
||||
# Essential emojis
|
||||
readonly ROCKET="🚀"
|
||||
readonly CHECK="✓"
|
||||
readonly ERROR="❌"
|
||||
readonly WARNING="⚠️"
|
||||
readonly SEARCH="🔍"
|
||||
readonly PALETTE="🎨"
|
||||
readonly MICROSCOPE="🔬"
|
||||
readonly MEMO="📝"
|
||||
readonly MAGNIFIER="🔎"
|
||||
readonly TEST_TUBE="🧪"
|
||||
readonly SPARKLES="✨"
|
||||
|
||||
print_header() {
|
||||
echo -e "\n${BOLD}${BLUE}${ROCKET} PHP-Flasher Code Quality Check ${ROCKET}${RESET}\n"
|
||||
echo -e "${BOLD}Date : ${RESET}${CYAN}$(date -u '+%Y-%m-%d %H:%M:%S') UTC${RESET}"
|
||||
echo -e "${BOLD}User : ${RESET}${MAGENTA}yoeunes${RESET}"
|
||||
echo -e "${BOLD}Branch : ${RESET}${GREEN}$(git rev-parse --abbrev-ref HEAD)${RESET}"
|
||||
echo -e "${BOLD}Directory : ${RESET}${BLUE}$(pwd)${RESET}\n"
|
||||
}
|
||||
|
||||
run_rector() {
|
||||
echo -e "${BOLD}${SEARCH} Running Rector${RESET}"
|
||||
|
||||
if $PHP_BINARY vendor/bin/rector; then
|
||||
echo -e "${CHECK} ${GREEN}Rector completed successfully${RESET}\n"
|
||||
return 0
|
||||
else
|
||||
echo -e "${WARNING} ${YELLOW}Rector found issues${RESET}\n"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
run_php_cs_fixer() {
|
||||
echo -e "${BOLD}${PALETTE} Running PHP-CS-Fixer${RESET}"
|
||||
|
||||
if $PHP_BINARY vendor/bin/php-cs-fixer fix -v; then
|
||||
echo -e "${CHECK} ${GREEN}PHP-CS-Fixer completed successfully${RESET}\n"
|
||||
return 0
|
||||
else
|
||||
echo -e "${WARNING} ${YELLOW}CS-Fixer found issues${RESET}\n"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
run_phpstan() {
|
||||
echo -e "${BOLD}${MICROSCOPE} Running PHPStan${RESET}"
|
||||
|
||||
if $PHP_BINARY vendor/bin/phpstan analyse --memory-limit=-1; then
|
||||
echo -e "${CHECK} ${GREEN}PHPStan analysis completed successfully${RESET}\n"
|
||||
return 0
|
||||
else
|
||||
echo -e "${WARNING} ${YELLOW}PHPStan found issues${RESET}\n"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
validate_composer_files() {
|
||||
echo -e "${BOLD}${MEMO} Validating Composer Files${RESET}"
|
||||
local validation_success=true
|
||||
|
||||
if ! composer validate --strict; then
|
||||
echo -e "${WARNING} ${YELLOW}Main composer.json validation failed${RESET}"
|
||||
validation_success=false
|
||||
fi
|
||||
|
||||
# Find and validate all composer.json files in src/
|
||||
find src/ -name "composer.json" | while read file; do
|
||||
echo -e "${DIM}Validating ${file}${RESET}"
|
||||
if ! composer validate --strict "$file"; then
|
||||
echo -e "${WARNING} ${YELLOW}Package validation failed for ${file}${RESET}"
|
||||
validation_success=false
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$validation_success" = true ]; then
|
||||
echo -e "${CHECK} ${GREEN}All composer.json files are valid${RESET}\n"
|
||||
return 0
|
||||
else
|
||||
echo -e "${WARNING} ${YELLOW}Some composer.json files have issues${RESET}\n"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
run_phplint() {
|
||||
echo -e "${BOLD}${MAGNIFIER} Running PHPLint${RESET}"
|
||||
|
||||
if $PHP_BINARY vendor/bin/phplint; then
|
||||
echo -e "${CHECK} ${GREEN}PHPLint completed successfully${RESET}\n"
|
||||
return 0
|
||||
else
|
||||
echo -e "${WARNING} ${YELLOW}PHPLint found issues${RESET}\n"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
run_phpunit() {
|
||||
echo -e "${BOLD}${TEST_TUBE} Running PHPUnit Tests${RESET}"
|
||||
|
||||
if $PHP_BINARY vendor/bin/phpunit; then
|
||||
echo -e "${CHECK} ${GREEN}All tests passed successfully${RESET}\n"
|
||||
return 0
|
||||
else
|
||||
echo -e "${WARNING} ${YELLOW}Tests failed${RESET}\n"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
run_vitest() {
|
||||
echo -e "${BOLD}${TEST_TUBE} Running Vitest Tests${RESET}"
|
||||
|
||||
if npm run test -- --run; then
|
||||
echo -e "${CHECK} ${GREEN}Vitest tests passed successfully${RESET}\n"
|
||||
return 0
|
||||
else
|
||||
echo -e "${WARNING} ${YELLOW}Vitest tests failed${RESET}\n"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
main() {
|
||||
local start_time=$(date +%s)
|
||||
local issues_found=false
|
||||
|
||||
print_header
|
||||
|
||||
# Run all quality tools
|
||||
run_rector || issues_found=true
|
||||
run_php_cs_fixer || issues_found=true
|
||||
run_phpstan || issues_found=true
|
||||
validate_composer_files || issues_found=true
|
||||
run_phplint || issues_found=true
|
||||
run_phpunit || issues_found=true
|
||||
run_vitest || issues_found=true
|
||||
|
||||
local end_time=$(date +%s)
|
||||
local duration=$((end_time - start_time))
|
||||
|
||||
# Summary
|
||||
echo -e "${BOLD}${CYAN}Quality Check Summary${RESET}"
|
||||
if [ "$issues_found" = true ]; then
|
||||
echo -e "${WARNING} ${YELLOW}Quality check completed with issues${RESET}"
|
||||
else
|
||||
echo -e "${SPARKLES} ${GREEN}All quality checks passed successfully${RESET}"
|
||||
fi
|
||||
echo -e "Duration : ${YELLOW}${duration}s${RESET}\n"
|
||||
|
||||
echo -e "${SPARKLES} ${BOLD}Quality Check Complete${RESET}"
|
||||
echo -e "${CHECK} All checks finished\n"
|
||||
|
||||
# We don't exit with error code because the original task continues despite failures
|
||||
exit 0
|
||||
}
|
||||
|
||||
main
|
||||
@@ -0,0 +1,225 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Set options
|
||||
set -o pipefail
|
||||
|
||||
# Define colors and styles
|
||||
readonly RESET='\033[0m'
|
||||
readonly BOLD='\033[1m'
|
||||
readonly DIM='\033[2m'
|
||||
readonly GREEN='\033[32m'
|
||||
readonly BLUE='\033[34m'
|
||||
readonly CYAN='\033[36m'
|
||||
readonly YELLOW='\033[33m'
|
||||
readonly RED='\033[31m'
|
||||
|
||||
# Define emoji
|
||||
readonly ROCKET="🚀"
|
||||
readonly NPM="📦"
|
||||
readonly CHECK="✓"
|
||||
readonly WARN="⚠️"
|
||||
readonly ERROR="❌"
|
||||
readonly LOADING="⏳"
|
||||
readonly SKIP="⏭️"
|
||||
|
||||
# Configuration
|
||||
readonly NPM_PACKAGES=(
|
||||
"src/Prime/Resources:@flasher/flasher"
|
||||
"src/Noty/Prime/Resources:@flasher/flasher-noty"
|
||||
"src/Notyf/Prime/Resources:@flasher/flasher-notyf"
|
||||
"src/SweetAlert/Prime/Resources:@flasher/flasher-sweetalert"
|
||||
"src/Toastr/Prime/Resources:@flasher/flasher-toastr"
|
||||
)
|
||||
|
||||
# Print functions
|
||||
print_header() {
|
||||
echo -e "\n${BOLD}${BLUE}╭──────────────────────────────────────────╮${RESET}"
|
||||
echo -e "${BOLD}${BLUE}│ ${ROCKET} PHP-Flasher NPM Release ${ROCKET} │${RESET}"
|
||||
echo -e "${BOLD}${BLUE}╰──────────────────────────────────────────╯${RESET}\n"
|
||||
echo -e " ${DIM}Date : $(date -u '+%Y-%m-%d %H:%M:%S') UTC${RESET}"
|
||||
echo -e " ${DIM}User : $(whoami)${RESET}"
|
||||
echo -e " ${DIM}Directory: $(pwd)${RESET}"
|
||||
}
|
||||
|
||||
print_section() {
|
||||
echo -e "\n${BOLD}${CYAN}┌─ $1 ${2:-}${RESET}"
|
||||
}
|
||||
|
||||
success_msg() {
|
||||
echo -e " ${GREEN}${CHECK} $*${RESET}"
|
||||
}
|
||||
|
||||
info_msg() {
|
||||
echo -e " ${BLUE}${LOADING} $*${RESET}"
|
||||
}
|
||||
|
||||
warning_msg() {
|
||||
echo -e " ${YELLOW}${WARN} $*${RESET}"
|
||||
}
|
||||
|
||||
error_msg() {
|
||||
echo -e " ${RED}${ERROR} $*${RESET}"
|
||||
}
|
||||
|
||||
skip_msg() {
|
||||
echo -e " ${YELLOW}${SKIP} $*${RESET}"
|
||||
}
|
||||
|
||||
print_summary() {
|
||||
local version=$1
|
||||
local duration=$2
|
||||
local success_count=$3
|
||||
local skipped_count=$4
|
||||
local failed_count=$5
|
||||
local failed_packages=("${@:6}")
|
||||
|
||||
print_section "Release Summary"
|
||||
echo -e "\n ${DIM}Version : ${BOLD}v${version}${RESET}"
|
||||
echo -e " ${DIM}Duration : ${BOLD}${duration}s${RESET}"
|
||||
|
||||
if [ "$success_count" -gt 0 ]; then
|
||||
echo -e "\n ${DIM}Published : ${GREEN}${success_count}${RESET} packages"
|
||||
fi
|
||||
|
||||
if [ "$skipped_count" -gt 0 ]; then
|
||||
echo -e "\n ${DIM}Skipped : ${YELLOW}${skipped_count}${RESET} packages"
|
||||
fi
|
||||
|
||||
if [ "$failed_count" -gt 0 ]; then
|
||||
echo -e "\n ${DIM}Failed : ${RED}${failed_count}${RESET} packages"
|
||||
echo -e "\n ${DIM}Failed packages:${RESET}"
|
||||
for package in "${failed_packages[@]}"; do
|
||||
echo -e " ${RED}• ${package}${RESET}"
|
||||
done
|
||||
fi
|
||||
|
||||
echo -e ""
|
||||
if [ "$success_count" -eq 0 ] && [ "$skipped_count" -gt 0 ]; then
|
||||
success_msg "All packages were already up to date! ${ROCKET}"
|
||||
elif [ "$success_count" -gt 0 ]; then
|
||||
success_msg "NPM release completed successfully! ${ROCKET}"
|
||||
elif [ "$failed_count" -gt 0 ]; then
|
||||
error_msg "NPM release completed with failures! ${ERROR}"
|
||||
fi
|
||||
}
|
||||
|
||||
# Check if version exists
|
||||
check_version_exists() {
|
||||
local package=$1
|
||||
local version=$2
|
||||
npm view "${package}@${version}" version >/dev/null 2>&1
|
||||
}
|
||||
|
||||
# Validate NPM is installed and logged in
|
||||
validate_npm() {
|
||||
print_section "NPM Authentication Check"
|
||||
|
||||
if ! command -v npm >/dev/null 2>&1; then
|
||||
error_msg "npm is not installed"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! npm whoami >/dev/null 2>&1; then
|
||||
error_msg "You are not logged in to npm. Please run 'npm login' first."
|
||||
return 1
|
||||
fi
|
||||
|
||||
success_msg "Authenticated as $(npm whoami)"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Process a single package
|
||||
process_package() {
|
||||
local path_and_name=$1
|
||||
local version=$2
|
||||
local path="${path_and_name%:*}"
|
||||
local package="${path_and_name#*:}"
|
||||
|
||||
print_section "Processing ${package}"
|
||||
|
||||
if [ ! -d "$path" ]; then
|
||||
warning_msg "Directory $path does not exist, skipping..."
|
||||
return 2
|
||||
fi
|
||||
|
||||
info_msg "Checking version ${version}..."
|
||||
if check_version_exists "$package" "$version"; then
|
||||
skip_msg "Version ${version} already exists for ${package}, skipping..."
|
||||
return 2
|
||||
fi
|
||||
|
||||
info_msg "Installing dependencies..."
|
||||
(cd "$path" && npm install --silent) || {
|
||||
error_msg "Failed to install dependencies"
|
||||
return 1
|
||||
}
|
||||
|
||||
info_msg "Updating package version..."
|
||||
(cd "$path" && npm version "$version" --no-git-tag-version --allow-same-version >/dev/null 2>&1) || true
|
||||
|
||||
info_msg "Publishing ${package}@${version}..."
|
||||
if (cd "$path" && npm publish --access public); then
|
||||
success_msg "Successfully published ${package}@${version}"
|
||||
return 0
|
||||
else
|
||||
error_msg "Failed to publish ${package}"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Main execution
|
||||
main() {
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo -e "\n${YELLOW}Usage: $0 <version>${RESET}"
|
||||
echo -e "Example: $0 2.1.5\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local VERSION=$1
|
||||
VERSION="${VERSION#v}"
|
||||
|
||||
print_header
|
||||
|
||||
# Validate npm authentication
|
||||
validate_npm || exit 1
|
||||
|
||||
# Track statistics
|
||||
local start_time=$(date +%s)
|
||||
local success_count=0
|
||||
local failed_count=0
|
||||
local skipped_count=0
|
||||
local failed_packages=()
|
||||
|
||||
# Process each package
|
||||
for package_info in "${NPM_PACKAGES[@]}"; do
|
||||
local package_name="${package_info#*:}"
|
||||
|
||||
process_package "$package_info" "$VERSION"
|
||||
local status=$?
|
||||
|
||||
case $status in
|
||||
0)
|
||||
((success_count++))
|
||||
;;
|
||||
1)
|
||||
((failed_count++))
|
||||
failed_packages+=("$package_name")
|
||||
;;
|
||||
2)
|
||||
((skipped_count++))
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Print summary
|
||||
local end_time=$(date +%s)
|
||||
local duration=$((end_time - start_time))
|
||||
|
||||
print_summary "$VERSION" "$duration" "$success_count" "$skipped_count" "$failed_count" "${failed_packages[@]}"
|
||||
|
||||
# Exit with failure if any package failed
|
||||
[ "$failed_count" -gt 0 ] && exit 1 || exit 0
|
||||
}
|
||||
|
||||
# Execute main function
|
||||
main "$@"
|
||||
+224
-61
@@ -1,80 +1,243 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
set -o pipefail
|
||||
|
||||
# Make sure the release tag is provided.
|
||||
if (( "$#" != 1 ))
|
||||
then
|
||||
echo "Tag has to be provided."
|
||||
# Colors and styles
|
||||
readonly RESET='\033[0m'
|
||||
readonly BOLD='\033[1m'
|
||||
readonly DIM='\033[2m'
|
||||
readonly UNDERLINE='\033[4m'
|
||||
readonly BLUE='\033[34m'
|
||||
readonly GREEN='\033[32m'
|
||||
readonly RED='\033[31m'
|
||||
readonly YELLOW='\033[33m'
|
||||
readonly CYAN='\033[36m'
|
||||
readonly MAGENTA='\033[35m'
|
||||
|
||||
exit 1
|
||||
fi
|
||||
# Essential emojis
|
||||
readonly ROCKET="🚀"
|
||||
readonly CHECK="✓"
|
||||
readonly ERROR="❌"
|
||||
readonly SKIP="⏭️"
|
||||
|
||||
RELEASE_BRANCH="2.x"
|
||||
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
||||
VERSION=$1
|
||||
# Configuration
|
||||
readonly RELEASE_BRANCH="2.x"
|
||||
readonly REPOSITORIES=(
|
||||
"flasher"
|
||||
"flasher-laravel"
|
||||
"flasher-symfony"
|
||||
"flasher-noty"
|
||||
"flasher-noty-laravel"
|
||||
"flasher-noty-symfony"
|
||||
"flasher-notyf"
|
||||
"flasher-notyf-laravel"
|
||||
"flasher-notyf-symfony"
|
||||
"flasher-sweetalert"
|
||||
"flasher-sweetalert-laravel"
|
||||
"flasher-sweetalert-symfony"
|
||||
"flasher-toastr"
|
||||
"flasher-toastr-laravel"
|
||||
"flasher-toastr-symfony"
|
||||
)
|
||||
|
||||
# Make sure current branch and release branch match.
|
||||
if [[ "$RELEASE_BRANCH" != "$CURRENT_BRANCH" ]]
|
||||
then
|
||||
echo "Release branch ($RELEASE_BRANCH) does not match the current active branch ($CURRENT_BRANCH)."
|
||||
print_header() {
|
||||
echo -e "\n${BOLD}${BLUE}${ROCKET} PHP-Flasher Release ${ROCKET}${RESET}\n"
|
||||
echo -e "${BOLD}Date : ${RESET}${CYAN}$(date -u '+%Y-%m-%d %H:%M:%S') UTC${RESET}"
|
||||
echo -e "${BOLD}User : ${RESET}${MAGENTA}$(whoami)${RESET}"
|
||||
echo -e "${BOLD}Branch : ${RESET}${GREEN}$RELEASE_BRANCH${RESET}"
|
||||
echo -e "${BOLD}Directory : ${RESET}${BLUE}$(pwd)${RESET}\n"
|
||||
}
|
||||
|
||||
exit 1
|
||||
fi
|
||||
draw_progress_bar() {
|
||||
local percent=$1
|
||||
local width=50
|
||||
local filled=$(((width * percent + 99) / 100)) # Rounded up division
|
||||
local empty=$((width - filled))
|
||||
|
||||
# Make sure the working directory is clear.
|
||||
if [[ ! -z "$(git status --porcelain)" ]]
|
||||
then
|
||||
echo "Your working directory is dirty. Did you forget to commit your changes?"
|
||||
echo -n "["
|
||||
printf "${GREEN}█%.0s${RESET}" $(seq 1 $filled)
|
||||
printf "${DIM}─%.0s${RESET}" $(seq 1 $empty)
|
||||
echo -n "] ${percent}%"
|
||||
}
|
||||
|
||||
exit 1
|
||||
fi
|
||||
check_tag_exists() {
|
||||
local repo=$1
|
||||
local tag=$2
|
||||
local remote_url="git@github.com:php-flasher/$repo.git"
|
||||
|
||||
# Make sure latest changes are fetched first.
|
||||
git fetch origin
|
||||
if git ls-remote --tags "$remote_url" | grep -q "refs/tags/$tag$"; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Make sure that release branch is in sync with origin.
|
||||
if [[ $(git rev-parse HEAD) != $(git rev-parse origin/$RELEASE_BRANCH) ]]
|
||||
then
|
||||
echo "Your branch is out of date with its upstream. Did you forget to pull or push any changes before releasing?"
|
||||
release_repository() {
|
||||
local repo=$1
|
||||
local version=$2
|
||||
local tmp_dir="/tmp/php-flasher"
|
||||
local remote_url="git@github.com:php-flasher/$repo.git"
|
||||
|
||||
exit 1
|
||||
fi
|
||||
echo -e "\nGitHub : ${UNDERLINE}${BLUE}https://github.com/php-flasher/${repo}${RESET}"
|
||||
echo -e "Tag : ${YELLOW}$version${RESET}"
|
||||
|
||||
# Always prepend with "v"
|
||||
if [[ $VERSION != v* ]]
|
||||
then
|
||||
VERSION="v$VERSION"
|
||||
fi
|
||||
if check_tag_exists "$repo" "$version"; then
|
||||
echo -e "${SKIP} ${YELLOW}Tag $version already exists, skipping...${RESET}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Tag PHPFlasher
|
||||
git tag "$VERSION"
|
||||
git push origin --tags --force
|
||||
# Clean and create temporary directory
|
||||
rm -rf "$tmp_dir"
|
||||
mkdir -p "$tmp_dir"
|
||||
|
||||
# Tag Repositories
|
||||
for REMOTE in flasher flasher-laravel flasher-symfony \
|
||||
flasher-noty flasher-noty-laravel flasher-noty-symfony \
|
||||
flasher-notyf flasher-notyf-laravel flasher-notyf-symfony \
|
||||
flasher-sweetalert flasher-sweetalert-laravel flasher-sweetalert-symfony \
|
||||
flasher-toastr flasher-toastr-laravel flasher-toastr-symfony
|
||||
do
|
||||
echo ""
|
||||
echo ""
|
||||
echo "Releasing $REMOTE";
|
||||
|
||||
TMP_DIR="/tmp/php-flasher"
|
||||
REMOTE_URL="git@github.com:php-flasher/$REMOTE.git"
|
||||
|
||||
rm -rf $TMP_DIR;
|
||||
mkdir $TMP_DIR;
|
||||
echo -e "${CYAN}Cloning repository...${RESET}"
|
||||
if ! git clone "$remote_url" "$tmp_dir" >/dev/null 2>&1; then
|
||||
echo -e "${ERROR} ${RED}Failed to clone repository${RESET}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
(
|
||||
cd $TMP_DIR;
|
||||
cd "$tmp_dir"
|
||||
echo -e "${CYAN}Creating tag $version...${RESET}"
|
||||
git checkout "$RELEASE_BRANCH" >/dev/null 2>&1
|
||||
git tag "$version"
|
||||
|
||||
git clone $REMOTE_URL .
|
||||
git checkout "$RELEASE_BRANCH";
|
||||
|
||||
git tag "$VERSION"
|
||||
git push origin --tags --force
|
||||
if ! git push origin --tags --force >/dev/null 2>&1; then
|
||||
echo -e "${ERROR} ${RED}Failed to push tag${RESET}"
|
||||
return 1
|
||||
fi
|
||||
)
|
||||
done
|
||||
|
||||
echo -e "${CHECK} ${GREEN}Successfully tagged${RESET}"
|
||||
return 0
|
||||
}
|
||||
|
||||
validate_version() {
|
||||
local version=$1
|
||||
if [[ ! $version =~ ^v?[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||
echo -e "\n${ERROR} ${RED}Invalid version format: $version${RESET}"
|
||||
echo -e "Version must be in format X.Y.Z or vX.Y.Z (e.g., 2.1.6 or v2.1.6)\n"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
validate_environment() {
|
||||
echo -e "${CYAN}Validating environment...${RESET}"
|
||||
local has_error=0
|
||||
|
||||
# Check branch
|
||||
local current_branch=$(git rev-parse --abbrev-ref HEAD)
|
||||
echo -ne "${CYAN}Checking branch...${RESET} "
|
||||
if [[ "$RELEASE_BRANCH" != "$current_branch" ]]; then
|
||||
echo -e "${ERROR} ${RED}Wrong branch: $current_branch (expected: $RELEASE_BRANCH)${RESET}"
|
||||
has_error=1
|
||||
else
|
||||
echo -e "${CHECK} ${GREEN}On correct branch: $current_branch${RESET}"
|
||||
fi
|
||||
|
||||
# Check working directory
|
||||
echo -ne "${CYAN}Checking working directory...${RESET} "
|
||||
if [[ ! -z "$(git status --porcelain)" ]]; then
|
||||
echo -e "${ERROR} ${RED}Working directory is not clean${RESET}"
|
||||
echo -e "${DIM}Hint: Commit or stash your changes first${RESET}"
|
||||
has_error=1
|
||||
else
|
||||
echo -e "${CHECK} ${GREEN}Working directory is clean${RESET}"
|
||||
fi
|
||||
|
||||
# Check sync with remote
|
||||
echo -ne "${CYAN}Checking remote synchronization...${RESET} "
|
||||
git fetch origin > /dev/null 2>&1
|
||||
local local_sha=$(git rev-parse HEAD)
|
||||
local remote_sha=$(git rev-parse origin/$RELEASE_BRANCH)
|
||||
|
||||
if [[ $local_sha != $remote_sha ]]; then
|
||||
echo -e "${ERROR} ${RED}Branch is not in sync with origin/$RELEASE_BRANCH${RESET}"
|
||||
echo -e "\n${YELLOW}Local SHA: ${local_sha}${RESET}"
|
||||
echo -e "${YELLOW}Remote SHA: ${remote_sha}${RESET}"
|
||||
echo -e "\n${DIM}To fix this, try:${RESET}"
|
||||
|
||||
# Check if we have unpushed commits
|
||||
if git rev-list origin/$RELEASE_BRANCH..$RELEASE_BRANCH --count > /dev/null 2>&1; then
|
||||
local ahead=$(git rev-list origin/$RELEASE_BRANCH..$RELEASE_BRANCH --count)
|
||||
local behind=$(git rev-list $RELEASE_BRANCH..origin/$RELEASE_BRANCH --count)
|
||||
|
||||
if [[ $ahead -gt 0 && $behind -gt 0 ]]; then
|
||||
echo -e "${YELLOW}Your branch is $ahead commits ahead and $behind commits behind origin/$RELEASE_BRANCH${RESET}"
|
||||
echo -e "1. ${CYAN}git pull origin $RELEASE_BRANCH${RESET} (to get remote changes)"
|
||||
echo -e "2. ${CYAN}git push origin $RELEASE_BRANCH${RESET} (to push your changes)"
|
||||
elif [[ $ahead -gt 0 ]]; then
|
||||
echo -e "${YELLOW}Your branch is $ahead commits ahead of origin/$RELEASE_BRANCH${RESET}"
|
||||
echo -e "Run: ${CYAN}git push origin $RELEASE_BRANCH${RESET}"
|
||||
elif [[ $behind -gt 0 ]]; then
|
||||
echo -e "${YELLOW}Your branch is $behind commits behind origin/$RELEASE_BRANCH${RESET}"
|
||||
echo -e "Run: ${CYAN}git pull origin $RELEASE_BRANCH${RESET}"
|
||||
fi
|
||||
fi
|
||||
has_error=1
|
||||
else
|
||||
echo -e "${CHECK} ${GREEN}Branch is in sync with remote${RESET}"
|
||||
fi
|
||||
|
||||
if [[ $has_error -eq 1 ]]; then
|
||||
echo -e "\n${ERROR} ${RED}Environment validation failed${RESET}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "\n${CHECK} ${GREEN}Environment validated successfully${RESET}\n"
|
||||
}
|
||||
|
||||
main() {
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo -e "${ERROR} ${RED}Version tag required${RESET}"
|
||||
echo -e "Usage: $0 <version>"
|
||||
echo -e "Example: $0 2.1.6\n"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local version=$1
|
||||
[[ $version != v* ]] && version="v$version"
|
||||
|
||||
print_header
|
||||
validate_version "$version"
|
||||
validate_environment
|
||||
|
||||
local success_count=0
|
||||
local skipped_count=0
|
||||
local failed_count=0
|
||||
local total_count=${#REPOSITORIES[@]}
|
||||
local start_time=$(date +%s)
|
||||
|
||||
for repo in "${REPOSITORIES[@]}"; do
|
||||
local current_count=$((success_count + skipped_count + failed_count + 1))
|
||||
local percent=$((current_count * 100 / total_count))
|
||||
|
||||
echo -e "\nProgress: ${BOLD}$current_count/$total_count${RESET}"
|
||||
# draw_progress_bar $percent
|
||||
|
||||
if release_repository "$repo" "$version"; then
|
||||
if check_tag_exists "$repo" "$version"; then
|
||||
((skipped_count++))
|
||||
else
|
||||
((success_count++))
|
||||
fi
|
||||
else
|
||||
((failed_count++))
|
||||
fi
|
||||
done
|
||||
|
||||
local end_time=$(date +%s)
|
||||
local duration=$((end_time - start_time))
|
||||
|
||||
# Summary
|
||||
echo -e "\n${BOLD}${CYAN}Release Summary${RESET}"
|
||||
echo -e "Successful : ${GREEN}$success_count${RESET}"
|
||||
echo -e "Skipped : ${YELLOW}$skipped_count${RESET}"
|
||||
[ $failed_count -gt 0 ] && echo -e "Failed : ${RED}$failed_count${RESET}"
|
||||
echo -e "Duration : ${YELLOW}${duration}s${RESET}"
|
||||
echo -e "Total repos: ${CYAN}$total_count${RESET}\n"
|
||||
|
||||
[ $failed_count -gt 0 ] && exit 1 || exit 0
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
@@ -1,108 +1,154 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Set the "errexit" options
|
||||
set -o errexit
|
||||
set -o pipefail
|
||||
|
||||
# Define colors and emoji for better visual feedback
|
||||
INDIGO='\033[0;94m'
|
||||
GREEN='\033[0;32m'
|
||||
NC='\033[0m' # No Color
|
||||
CHECK_MARK="✅"
|
||||
CROSS_MARK="❌"
|
||||
# Colors and styles
|
||||
readonly RESET='\033[0m'
|
||||
readonly BOLD='\033[1m'
|
||||
readonly DIM='\033[2m'
|
||||
readonly UNDERLINE='\033[4m'
|
||||
readonly BLUE='\033[34m'
|
||||
readonly GREEN='\033[32m'
|
||||
readonly RED='\033[31m'
|
||||
readonly YELLOW='\033[33m'
|
||||
readonly CYAN='\033[36m'
|
||||
readonly MAGENTA='\033[35m'
|
||||
|
||||
# Initialize global flags
|
||||
DEBUG=0
|
||||
DRY_RUN=0
|
||||
# Essential emojis
|
||||
readonly ROCKET="🚀"
|
||||
readonly CHECK="✓"
|
||||
readonly ERROR="❌"
|
||||
|
||||
# Process command-line arguments
|
||||
for arg in "$@"; do
|
||||
case $arg in
|
||||
--debug)
|
||||
DEBUG=1
|
||||
shift
|
||||
;;
|
||||
--dry-run)
|
||||
DRY_RUN=1
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
# Unknown option
|
||||
;;
|
||||
esac
|
||||
done
|
||||
# Repository mappings
|
||||
declare -A REPOSITORIES=(
|
||||
# Core packages
|
||||
["src/Prime"]="flasher"
|
||||
["src/Laravel"]="flasher-laravel"
|
||||
["src/Symfony"]="flasher-symfony"
|
||||
|
||||
# Debug message function
|
||||
debug_msg() {
|
||||
if [ "$DEBUG" -eq 1 ]; then
|
||||
echo -e "${INDIGO}Debug: $*${NC}"
|
||||
fi
|
||||
}
|
||||
# Toastr packages
|
||||
["src/Toastr/Prime"]="flasher-toastr"
|
||||
["src/Toastr/Laravel"]="flasher-toastr-laravel"
|
||||
["src/Toastr/Symfony"]="flasher-toastr-symfony"
|
||||
|
||||
# Define remotes
|
||||
REMOTES=(
|
||||
'src/Prime:flasher'
|
||||
'src/Laravel:flasher-laravel'
|
||||
'src/Symfony:flasher-symfony'
|
||||
# Notyf packages
|
||||
["src/Notyf/Prime"]="flasher-notyf"
|
||||
["src/Notyf/Laravel"]="flasher-notyf-laravel"
|
||||
["src/Notyf/Symfony"]="flasher-notyf-symfony"
|
||||
|
||||
'src/Toastr/Prime:flasher-toastr'
|
||||
'src/Toastr/Laravel:flasher-toastr-laravel'
|
||||
'src/Toastr/Symfony:flasher-toastr-symfony'
|
||||
# SweetAlert packages
|
||||
["src/SweetAlert/Prime"]="flasher-sweetalert"
|
||||
["src/SweetAlert/Laravel"]="flasher-sweetalert-laravel"
|
||||
["src/SweetAlert/Symfony"]="flasher-sweetalert-symfony"
|
||||
|
||||
'src/Notyf/Prime:flasher-notyf'
|
||||
'src/Notyf/Laravel:flasher-notyf-laravel'
|
||||
'src/Notyf/Symfony:flasher-notyf-symfony'
|
||||
|
||||
'src/SweetAlert/Prime:flasher-sweetalert'
|
||||
'src/SweetAlert/Laravel:flasher-sweetalert-laravel'
|
||||
'src/SweetAlert/Symfony:flasher-sweetalert-symfony'
|
||||
|
||||
'src/Noty/Prime:flasher-noty'
|
||||
'src/Noty/Laravel:flasher-noty-laravel'
|
||||
'src/Noty/Symfony:flasher-noty-symfony'
|
||||
# Noty packages
|
||||
["src/Noty/Prime"]="flasher-noty"
|
||||
["src/Noty/Laravel"]="flasher-noty-laravel"
|
||||
["src/Noty/Symfony"]="flasher-noty-symfony"
|
||||
)
|
||||
|
||||
# Function to get the current git branch name
|
||||
function current_branch() {
|
||||
git rev-parse --abbrev-ref HEAD
|
||||
print_header() {
|
||||
echo -e "\n${BOLD}${BLUE}${ROCKET} PHP-Flasher Split ${ROCKET}${RESET}\n"
|
||||
echo -e "${BOLD}Date : ${RESET}${CYAN}$(date -u '+%Y-%m-%d %H:%M:%S') UTC${RESET}"
|
||||
echo -e "${BOLD}User : ${RESET}${MAGENTA}$(whoami)${RESET}"
|
||||
echo -e "${BOLD}Branch : ${RESET}${GREEN}$(git rev-parse --abbrev-ref HEAD)${RESET}"
|
||||
echo -e "${BOLD}Directory : ${RESET}${BLUE}$(pwd)${RESET}\n"
|
||||
}
|
||||
|
||||
# Define a function to split and push code to a remote repository
|
||||
function split() {
|
||||
local prefix_and_remote="$1"
|
||||
local prefix="${prefix_and_remote%:*}"
|
||||
local remote="${prefix_and_remote#*:}"
|
||||
local current_branch=$(current_branch)
|
||||
process_split() {
|
||||
local prefix=$1
|
||||
local remote=${REPOSITORIES[$prefix]}
|
||||
local branch=$(git rev-parse --abbrev-ref HEAD)
|
||||
local repo_url="https://github.com/php-flasher/${remote}"
|
||||
local packagist_url="https://packagist.org/packages/php-flasher/${remote}"
|
||||
|
||||
# Add remote if it does not exist (ignoring errors silently)
|
||||
if git remote add "$remote" "git@github.com:php-flasher/$remote.git" 2>/dev/null; then
|
||||
echo -e "${GREEN}Added remote ${INDIGO}$remote${NC} ${CHECK_MARK}"
|
||||
else
|
||||
debug_msg "Remote $remote already exists or could not be added."
|
||||
echo -e "\nGitHub : ${UNDERLINE}${BLUE}${repo_url}${RESET}"
|
||||
echo -e "Package : ${UNDERLINE}${BLUE}${packagist_url}${RESET}"
|
||||
echo -e "Prefix : ${YELLOW}$prefix${RESET}"
|
||||
echo -e "Branch : ${GREEN}$branch${RESET}\n"
|
||||
|
||||
# Split the repository
|
||||
echo -e "${CYAN}Splitting code...${RESET}"
|
||||
local sha1
|
||||
if ! sha1=$(./bin/splitsh-lite --prefix="$prefix" 2>/dev/null); then
|
||||
echo -e "${ERROR} ${RED}Split failed${RESET}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Split the code using the splitsh-lite utility
|
||||
SHA1=$(./bin/splitsh-lite --prefix="$prefix")
|
||||
debug_msg "SHA1 for $prefix is $SHA1."
|
||||
echo -e "${CHECK} Split complete (SHA: ${YELLOW}${sha1:0:8}${RESET})"
|
||||
echo -e "${CYAN}Pushing to remote...${RESET}"
|
||||
|
||||
# Push the code to the remote repository on the same branch as the current branch
|
||||
if [ "$DRY_RUN" -eq 0 ]; then
|
||||
git push "$remote" "$SHA1:refs/heads/$current_branch" -f
|
||||
else
|
||||
echo -e "${INDIGO}Dry run: Would push $SHA1 to $remote on branch $current_branch${NC}"
|
||||
if ! git push "$remote" "$sha1:refs/heads/$branch" -f > /dev/null 2>&1; then
|
||||
echo -e "${ERROR} ${RED}Failed to push to $remote${RESET}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo -e "${CHECK} ${GREEN}Pushed to $remote (branch: $branch)${RESET}"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Pull the latest code from the origin repository
|
||||
if [ "$DRY_RUN" -eq 0 ]; then
|
||||
echo -e "${INDIGO}Pulling the latest code from the origin repository on branch ${current_branch}...${NC}"
|
||||
git fetch origin "$current_branch"
|
||||
else
|
||||
echo -e "${INDIGO}Dry run: Would fetch latest code for branch $current_branch from the origin repository.${NC}"
|
||||
fi
|
||||
update_repository() {
|
||||
echo -e "\n${CYAN}Fetching latest changes...${RESET}"
|
||||
if ! git fetch origin "$(git rev-parse --abbrev-ref HEAD)" > /dev/null 2>&1; then
|
||||
echo -e "${ERROR} ${RED}Failed to fetch latest changes, continuing...${RESET}"
|
||||
else
|
||||
echo -e "${CHECK} ${GREEN}Repository updated successfully${RESET}"
|
||||
fi
|
||||
echo
|
||||
}
|
||||
|
||||
# Iterate over the remotes and split and push the code
|
||||
for remote in "${REMOTES[@]}"; do
|
||||
split "$remote"
|
||||
done
|
||||
draw_progress_bar() {
|
||||
local percent=$1
|
||||
local width=50
|
||||
local filled=$(( (width * percent + 99) / 100 )) # Rounded up division
|
||||
local empty=$(( width - filled ))
|
||||
|
||||
echo -e "${GREEN}All done!${NC} ${CHECK_MARK}"
|
||||
echo -n "["
|
||||
printf "${GREEN}█%.0s${RESET}" $(seq 1 $filled)
|
||||
printf "${DIM}─%.0s${RESET}" $(seq 1 $empty)
|
||||
echo -n "] ${percent}%"
|
||||
}
|
||||
|
||||
main() {
|
||||
print_header
|
||||
update_repository
|
||||
|
||||
local success_count=0
|
||||
local failed_count=0
|
||||
local total_count=${#REPOSITORIES[@]}
|
||||
local start_time=$(date +%s)
|
||||
|
||||
for prefix in "${!REPOSITORIES[@]}"; do
|
||||
local current_count=$((success_count + failed_count + 1))
|
||||
local percent=$((current_count * 100 / total_count))
|
||||
|
||||
echo -e "\nProgress: ${BOLD}$current_count/$total_count${RESET}"
|
||||
# draw_progress_bar $percent
|
||||
|
||||
if process_split "$prefix"; then
|
||||
((success_count++))
|
||||
else
|
||||
((failed_count++))
|
||||
fi
|
||||
done
|
||||
|
||||
local end_time=$(date +%s)
|
||||
local duration=$((end_time - start_time))
|
||||
|
||||
# Summary
|
||||
echo -e "\n${BOLD}${CYAN}Split Summary${RESET}"
|
||||
echo -e "Successful : ${GREEN}$success_count${RESET}"
|
||||
[ $failed_count -gt 0 ] && echo -e "Failed : ${RED}$failed_count${RESET}"
|
||||
echo -e "Duration : ${YELLOW}${duration}s${RESET}"
|
||||
echo -e "Total repos : ${CYAN}$total_count${RESET}"
|
||||
|
||||
# Links
|
||||
echo -e "\n${BOLD}${CYAN}Quick Links${RESET}"
|
||||
echo -e "Packagist : ${UNDERLINE}${BLUE}https://packagist.org/packages/php-flasher/${RESET}"
|
||||
echo -e "NPM : ${UNDERLINE}${BLUE}https://www.npmjs.com/org/flasher${RESET}"
|
||||
echo -e "GitHub : ${UNDERLINE}${BLUE}https://github.com/php-flasher${RESET}\n"
|
||||
|
||||
[ $failed_count -gt 0 ] && exit 1 || exit 0
|
||||
}
|
||||
|
||||
main
|
||||
|
||||
Executable
+331
@@ -0,0 +1,331 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Set options
|
||||
set -e
|
||||
set -o pipefail
|
||||
|
||||
# Define colors and styles
|
||||
readonly RESET='\033[0m'
|
||||
readonly BOLD='\033[1m'
|
||||
readonly DIM='\033[2m'
|
||||
readonly ITALIC='\033[3m'
|
||||
readonly UNDERLINE='\033[4m'
|
||||
readonly RED='\033[31m'
|
||||
readonly GREEN='\033[32m'
|
||||
readonly YELLOW='\033[33m'
|
||||
readonly BLUE='\033[34m'
|
||||
readonly MAGENTA='\033[35m'
|
||||
readonly CYAN='\033[36m'
|
||||
readonly WHITE='\033[37m'
|
||||
|
||||
# Define emoji
|
||||
readonly ROCKET="🚀"
|
||||
readonly PACKAGE="📦"
|
||||
readonly CALENDAR="📅"
|
||||
readonly CLOCK="🕒"
|
||||
readonly INFO="ℹ️"
|
||||
readonly WARNING="⚠️"
|
||||
readonly CHECK="✓"
|
||||
readonly BRANCH="🌿"
|
||||
readonly TAG="🏷️"
|
||||
readonly GITHUB="⭐"
|
||||
readonly STAR="⭐"
|
||||
readonly NPM="📦"
|
||||
readonly PACKAGIST="🎯"
|
||||
|
||||
# Configuration
|
||||
readonly ORGANIZATION="php-flasher"
|
||||
readonly MAIN_BRANCH="2.x"
|
||||
readonly REPOSITORIES=(
|
||||
"flasher"
|
||||
"flasher-laravel"
|
||||
"flasher-symfony"
|
||||
"flasher-noty"
|
||||
"flasher-noty-laravel"
|
||||
"flasher-noty-symfony"
|
||||
"flasher-notyf"
|
||||
"flasher-notyf-laravel"
|
||||
"flasher-notyf-symfony"
|
||||
"flasher-sweetalert"
|
||||
"flasher-sweetalert-laravel"
|
||||
"flasher-sweetalert-symfony"
|
||||
"flasher-toastr"
|
||||
"flasher-toastr-laravel"
|
||||
"flasher-toastr-symfony"
|
||||
)
|
||||
|
||||
# Print functions
|
||||
print_header() {
|
||||
echo -e "\n${BOLD}${BLUE}╭──────────────────────────────────────────╮${RESET}"
|
||||
echo -e "${BOLD}${BLUE}│ ${ROCKET} PHP-Flasher Status ${ROCKET} │${RESET}"
|
||||
echo -e "${BOLD}${BLUE}╰──────────────────────────────────────────╯${RESET}\n"
|
||||
echo -e " ${DIM}Date : $(date -u '+%Y-%m-%d %H:%M:%S') UTC${RESET}"
|
||||
echo -e " ${DIM}User : $(whoami)${RESET}"
|
||||
echo -e " ${DIM}Directory: $(pwd)${RESET}"
|
||||
}
|
||||
|
||||
print_section() {
|
||||
echo -e "\n${BOLD}${CYAN} $1 ${2:-}${RESET}"
|
||||
}
|
||||
|
||||
warning_msg() {
|
||||
echo -e " ${YELLOW}${WARNING} $*${RESET}"
|
||||
}
|
||||
|
||||
success_msg() {
|
||||
echo -e " ${GREEN}${CHECK} $*${RESET}"
|
||||
}
|
||||
|
||||
error_msg() {
|
||||
echo -e " ${RED}${ERROR} $*${RESET}"
|
||||
}
|
||||
|
||||
info_msg() {
|
||||
echo -e "${BLUE}${INFO} $*${RESET}"
|
||||
}
|
||||
|
||||
# Get the latest tag for a repository
|
||||
get_latest_tag() {
|
||||
local repo=$1
|
||||
git ls-remote --tags --refs "git@github.com:${ORGANIZATION}/${repo}.git" |
|
||||
sort -t '/' -k 3 -V |
|
||||
tail -n1 |
|
||||
awk -F/ '{print $3}'
|
||||
}
|
||||
|
||||
# Get commit count since last tag
|
||||
get_commit_count_since_tag() {
|
||||
local repo=$1
|
||||
local tag=$2
|
||||
git rev-list "${tag}..HEAD" --count 2>/dev/null || echo "0"
|
||||
}
|
||||
|
||||
# Get repository statistics
|
||||
get_repo_stats() {
|
||||
local repo=$1
|
||||
local tmp_dir="/tmp/php-flasher-status/${repo}"
|
||||
|
||||
mkdir -p "$tmp_dir"
|
||||
if [ ! -d "$tmp_dir/.git" ]; then
|
||||
git clone -q "git@github.com:${ORGANIZATION}/${repo}.git" "$tmp_dir" 2>/dev/null
|
||||
fi
|
||||
|
||||
(
|
||||
cd "$tmp_dir"
|
||||
git fetch -q origin 2>/dev/null
|
||||
echo "$(git rev-parse --short HEAD)|$(git rev-parse --abbrev-ref HEAD)|$(git log -1 --format='%cr')|$(git log -1 --format='%s')"
|
||||
)
|
||||
}
|
||||
|
||||
# Check composer.json version
|
||||
check_composer_version() {
|
||||
local file="composer.json"
|
||||
if [ -f "$file" ]; then
|
||||
grep -o '"version": *"[^"]*"' "$file" 2>/dev/null | cut -d'"' -f4 || echo "N/A"
|
||||
else
|
||||
echo "N/A"
|
||||
fi
|
||||
}
|
||||
|
||||
# Add curl with proper user agent for API calls
|
||||
curl_cmd() {
|
||||
# You can set your GitHub token as an environment variable
|
||||
local gh_token=${GITHUB_TOKEN:-""}
|
||||
local auth_header=""
|
||||
if [ ! -z "$gh_token" ]; then
|
||||
auth_header="-H \"Authorization: token $gh_token\""
|
||||
fi
|
||||
|
||||
curl -s -H "User-Agent: PHP-Flasher-Status-Check" $auth_header "$@"
|
||||
}
|
||||
|
||||
# Get GitHub stars for a repository
|
||||
get_github_stars() {
|
||||
local repo=$1
|
||||
local response=$(curl_cmd "https://api.github.com/repos/${ORGANIZATION}/${repo}")
|
||||
local stars=$(echo "$response" | grep -o '"stargazers_count":[0-9]*' | cut -d':' -f2)
|
||||
echo "${stars:-0}"
|
||||
}
|
||||
|
||||
# Get Packagist version
|
||||
get_packagist_version() {
|
||||
local package=$1
|
||||
local response=$(curl -s -f "https://repo.packagist.org/p2/php-flasher/${package}.json")
|
||||
if [ $? -eq 0 ] && [ ! -z "$response" ]; then
|
||||
local version=$(echo "$response" | grep -o '"latest":"[^"]*"' | cut -d'"' -f4)
|
||||
if [ ! -z "$version" ]; then
|
||||
echo "$version"
|
||||
else
|
||||
echo "N/A"
|
||||
fi
|
||||
else
|
||||
echo "N/A"
|
||||
fi
|
||||
}
|
||||
|
||||
# Get NPM version
|
||||
get_npm_version() {
|
||||
local package=$1
|
||||
# Convert package name format
|
||||
if [[ "$package" == "flasher" ]]; then
|
||||
package="flasher"
|
||||
elif [[ "$package" == *"-prime" ]]; then
|
||||
# Remove -prime suffix for npm package name
|
||||
package=${package%-prime}
|
||||
elif [[ "$package" == *"-laravel" || "$package" == *"-symfony" ]]; then
|
||||
# These packages don't have npm versions
|
||||
echo "N/A"
|
||||
return
|
||||
fi
|
||||
|
||||
local response=$(curl_cmd "https://registry.npmjs.org/@flasher/${package}/latest")
|
||||
local version=$(echo "$response" | grep -o '"version":"[^"]*"' | cut -d'"' -f4)
|
||||
echo "${version:-N/A}"
|
||||
}
|
||||
|
||||
# Display repository information
|
||||
display_repo_info() {
|
||||
local repo=$1
|
||||
local latest_tag=$(get_latest_tag "$repo")
|
||||
local stats=($(get_repo_stats "$repo" | tr '|' ' '))
|
||||
local github_stars=$(get_github_stars "$repo")
|
||||
local npm_version="N/A"
|
||||
local packagist_version="N/A"
|
||||
|
||||
# Get NPM version for specific packages
|
||||
if [[ "$repo" == "flasher" || \
|
||||
"$repo" == "flasher-noty" || \
|
||||
"$repo" == "flasher-notyf" || \
|
||||
"$repo" == "flasher-sweetalert" || \
|
||||
"$repo" == "flasher-toastr" ]]; then
|
||||
npm_version=$(get_npm_version "$repo")
|
||||
fi
|
||||
|
||||
# Get Packagist version
|
||||
packagist_version=$(get_packagist_version "$repo")
|
||||
|
||||
# Display repository information
|
||||
echo -e "\n${BOLD}${MAGENTA} ${PACKAGE} ${repo}${RESET}"
|
||||
echo -e " ${BRANCH} Branch : ${stats[1]:-unknown}"
|
||||
echo -e " ${TAG} Latest Tag : ${latest_tag:-none}"
|
||||
echo -e " ${STAR} Stars : ${github_stars}"
|
||||
echo -e " ${PACKAGIST} Packagist : v${packagist_version}"
|
||||
|
||||
if [ "$npm_version" != "N/A" ]; then
|
||||
echo -e " ${NPM} NPM : v${npm_version}"
|
||||
fi
|
||||
|
||||
echo -e " ${GITHUB} Last Commit : ${stats[0]:-unknown} (${stats[2]:-unknown})"
|
||||
echo -e " ${INFO} Message : ${stats[3]:-unknown}"
|
||||
|
||||
local commits_since_tag=$(get_commit_count_since_tag "$repo" "$latest_tag")
|
||||
if [ "$commits_since_tag" -gt 0 ]; then
|
||||
warning_msg "$commits_since_tag commit(s) since last tag"
|
||||
fi
|
||||
}
|
||||
|
||||
# Check git status
|
||||
check_git_status() {
|
||||
print_section "Git Status" "${GITHUB}"
|
||||
|
||||
local current_branch=$(git rev-parse --abbrev-ref HEAD)
|
||||
echo -e " ${BRANCH} Current Branch : ${current_branch}"
|
||||
|
||||
if [ "$current_branch" != "$MAIN_BRANCH" ]; then
|
||||
warning_msg " Not on main branch ($MAIN_BRANCH)"
|
||||
fi
|
||||
|
||||
if [[ ! -z "$(git status --porcelain)" ]]; then
|
||||
warning_msg " Working directory is not clean"
|
||||
git status --short | sed 's/^/ /'
|
||||
else
|
||||
success_msg " Working directory is clean"
|
||||
fi
|
||||
|
||||
local behind=$(git rev-list HEAD..origin/$current_branch --count 2>/dev/null || echo "0")
|
||||
local ahead=$(git rev-list origin/$current_branch..HEAD --count 2>/dev/null || echo "0")
|
||||
|
||||
if [ "$behind" -gt 0 ]; then
|
||||
warning_msg " Branch is behind by $behind commit(s)"
|
||||
fi
|
||||
if [ "$ahead" -gt 0 ]; then
|
||||
warning_msg " Branch is ahead by $ahead commit(s)"
|
||||
fi
|
||||
if [ "$behind" -eq 0 ] && [ "$ahead" -eq 0 ]; then
|
||||
success_msg " Branch is up to date with origin"
|
||||
fi
|
||||
}
|
||||
|
||||
# Check dependencies
|
||||
check_dependencies() {
|
||||
print_section "Dependencies" "${PACKAGE}"
|
||||
|
||||
if [ -f "composer.json" ]; then
|
||||
echo -e " ${BOLD}Composer Dependencies:${RESET}"
|
||||
composer show | grep "php-flasher/" | sed 's/^/ /' || echo " No PHP-Flasher dependencies found"
|
||||
fi
|
||||
|
||||
if [ -f "package.json" ]; then
|
||||
echo -e "\n ${BOLD}NPM Dependencies:${RESET}"
|
||||
npm list | grep "@flasher/" | sed 's/^/ /' || echo " No Flasher dependencies found"
|
||||
fi
|
||||
}
|
||||
|
||||
# Display modified files
|
||||
display_modified_files() {
|
||||
print_section "Modified Files" "📝"
|
||||
|
||||
local modified_files=$(git diff --name-only)
|
||||
if [ ! -z "$modified_files" ]; then
|
||||
echo -e " ${BOLD}Modified files:${RESET}"
|
||||
echo "$modified_files" | sed 's/^/ /'
|
||||
else
|
||||
success_msg " No modified files"
|
||||
fi
|
||||
}
|
||||
|
||||
# Main execution
|
||||
main() {
|
||||
print_header
|
||||
|
||||
# Check current repository status
|
||||
check_git_status
|
||||
|
||||
# Check dependencies
|
||||
check_dependencies
|
||||
|
||||
# Display modified files
|
||||
display_modified_files
|
||||
|
||||
# Display repositories information
|
||||
print_section "Repositories Status" "${PACKAGE}"
|
||||
for repo in "${REPOSITORIES[@]}"; do
|
||||
display_repo_info "$repo"
|
||||
done
|
||||
|
||||
# Display release readiness
|
||||
print_section "Release Readiness" "${ROCKET}"
|
||||
local ready=true
|
||||
|
||||
if [ ! -z "$(git status --porcelain)" ]; then
|
||||
warning_msg "Working directory is not clean"
|
||||
ready=false
|
||||
fi
|
||||
|
||||
if [ "$(git rev-parse --abbrev-ref HEAD)" != "$MAIN_BRANCH" ]; then
|
||||
warning_msg "Not on main branch ($MAIN_BRANCH)"
|
||||
ready=false
|
||||
fi
|
||||
|
||||
if $ready; then
|
||||
success_msg "Ready for release!"
|
||||
echo -e "\n${BOLD}${GREEN}Suggested next steps:${RESET}"
|
||||
echo -e "1. Run: ${ITALIC}./bin/split${RESET}"
|
||||
echo -e "2. Run: ${ITALIC}./bin/release <version>${RESET}"
|
||||
else
|
||||
warning_msg "Not ready for release. Please fix the issues above."
|
||||
fi
|
||||
}
|
||||
|
||||
# Execute main function
|
||||
main
|
||||
Executable
+124
@@ -0,0 +1,124 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -o pipefail
|
||||
|
||||
# Colors and styles
|
||||
readonly RESET='\033[0m'
|
||||
readonly BOLD='\033[1m'
|
||||
readonly DIM='\033[2m'
|
||||
readonly UNDERLINE='\033[4m'
|
||||
readonly BLUE='\033[34m'
|
||||
readonly GREEN='\033[32m'
|
||||
readonly RED='\033[31m'
|
||||
readonly YELLOW='\033[33m'
|
||||
readonly CYAN='\033[36m'
|
||||
readonly MAGENTA='\033[35m'
|
||||
|
||||
# Essential emojis
|
||||
readonly ROCKET="🚀"
|
||||
readonly CHECK="✓"
|
||||
readonly ERROR="❌"
|
||||
readonly PACKAGE="📦"
|
||||
readonly SEARCH="🔍"
|
||||
readonly HAMMER="🏗️"
|
||||
readonly SPARKLES="✨"
|
||||
readonly WARNING="⚠️"
|
||||
|
||||
print_header() {
|
||||
echo -e "\n${BOLD}${BLUE}${ROCKET} PHP-Flasher Update ${ROCKET}${RESET}\n"
|
||||
echo -e "${BOLD}Date : ${RESET}${CYAN}$(date -u '+%Y-%m-%d %H:%M:%S') UTC${RESET}"
|
||||
echo -e "${BOLD}User : ${RESET}${MAGENTA}$(whoami)${RESET}"
|
||||
echo -e "${BOLD}Branch : ${RESET}${GREEN}$(git rev-parse --abbrev-ref HEAD)${RESET}"
|
||||
echo -e "${BOLD}Directory : ${RESET}${BLUE}$(pwd)${RESET}\n"
|
||||
}
|
||||
|
||||
update_composer_dependencies() {
|
||||
echo -e "${BOLD}${PACKAGE} Composer Dependencies${RESET}"
|
||||
|
||||
if composer update --prefer-lowest -W; then
|
||||
echo -e "${CHECK} ${GREEN}Dependencies updated successfully${RESET}\n"
|
||||
return 0
|
||||
else
|
||||
echo -e "${ERROR} ${RED}Failed to update Composer dependencies${RESET}\n"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
check_npm_updates() {
|
||||
echo -e "${BOLD}${SEARCH} NPM Updates Check${RESET}"
|
||||
|
||||
# Run the commands and capture their exit codes
|
||||
ncu -u
|
||||
NCU_EXIT_CODE=$?
|
||||
|
||||
npm run ncu --workspaces
|
||||
NPM_EXIT_CODE=$?
|
||||
|
||||
# Check if both commands were successful
|
||||
if [ $NCU_EXIT_CODE -eq 0 ] && [ $NPM_EXIT_CODE -eq 0 ]; then
|
||||
echo -e "${CHECK} ${GREEN}NPM check completed successfully${RESET}\n"
|
||||
else
|
||||
echo -e "${WARNING} ${YELLOW}NPM check failed, continuing...${RESET}\n"
|
||||
fi
|
||||
|
||||
return 0 # Continue regardless of outcome
|
||||
}
|
||||
|
||||
update_npm_dependencies() {
|
||||
echo -e "${BOLD}${PACKAGE} NPM Dependencies${RESET}"
|
||||
|
||||
if npm install --force; then
|
||||
echo -e "${CHECK} ${GREEN}NPM dependencies installed successfully${RESET}\n"
|
||||
return 0
|
||||
else
|
||||
echo -e "${WARNING} ${YELLOW}NPM install failed, continuing...${RESET}\n"
|
||||
return 0 # Continue despite failure
|
||||
fi
|
||||
}
|
||||
|
||||
build_assets() {
|
||||
echo -e "${BOLD}${HAMMER} Building Assets${RESET}"
|
||||
|
||||
if npm run build; then
|
||||
echo -e "${CHECK} ${GREEN}Assets built successfully${RESET}\n"
|
||||
return 0
|
||||
else
|
||||
echo -e "${WARNING} ${YELLOW}Build failed, continuing...${RESET}\n"
|
||||
return 0 # Continue despite failure
|
||||
fi
|
||||
}
|
||||
|
||||
main() {
|
||||
local start_time=$(date +%s)
|
||||
local success=true
|
||||
|
||||
print_header
|
||||
|
||||
# Update composer dependencies
|
||||
update_composer_dependencies || success=false
|
||||
|
||||
# Check NPM updates
|
||||
check_npm_updates
|
||||
|
||||
# Update NPM dependencies
|
||||
update_npm_dependencies
|
||||
|
||||
# Build assets
|
||||
build_assets
|
||||
|
||||
local end_time=$(date +%s)
|
||||
local duration=$((end_time - start_time))
|
||||
|
||||
# Summary
|
||||
echo -e "${BOLD}${CYAN}Update Summary${RESET}"
|
||||
if [ "$success" = true ]; then
|
||||
echo -e "${SPARKLES} ${GREEN}Update completed successfully${RESET}"
|
||||
else
|
||||
echo -e "${WARNING} ${YELLOW}Update completed with some issues${RESET}"
|
||||
fi
|
||||
echo -e "Duration : ${YELLOW}${duration}s${RESET}\n"
|
||||
|
||||
[ "$success" = true ] && exit 0 || exit 1
|
||||
}
|
||||
|
||||
main
|
||||
+29
-25
@@ -21,34 +21,38 @@
|
||||
"prefer-stable": true,
|
||||
"require": {
|
||||
"php": ">=8.2",
|
||||
"ext-intl": "*"
|
||||
"ext-intl": "*",
|
||||
"illuminate/contracts": "^11.0|^12.0|^13.0",
|
||||
"illuminate/routing": "^11.0|^12.0|^13.0",
|
||||
"illuminate/support": "^11.0|^12.0|^13.0",
|
||||
"laravel/octane": "^2.3",
|
||||
"livewire/livewire": "^3.0",
|
||||
"paragonie/random_compat": "^2.0",
|
||||
"psr/container": "^1.1|^2.0",
|
||||
"symfony/config": "^7.0|^8.0",
|
||||
"symfony/console": "^7.0|^8.0",
|
||||
"symfony/dependency-injection": "^7.0|^8.0",
|
||||
"symfony/framework-bundle": "^7.0|^8.0",
|
||||
"symfony/http-kernel": "^7.0|^8.0",
|
||||
"symfony/translation": "^7.0|^8.0",
|
||||
"symfony/twig-bundle": "^7.0|^8.0",
|
||||
"symfony/ux-twig-component": "^2.19",
|
||||
"yoeunes/regex-parser": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"illuminate/routing": "^11.0",
|
||||
"illuminate/support": "^11.0",
|
||||
"larastan/larastan": "^2.9.6",
|
||||
"laravel/octane": "^2.3",
|
||||
"livewire/livewire": "^3.3",
|
||||
"larastan/larastan": "^2.9.9",
|
||||
"mockery/mockery": "^1.6.12",
|
||||
"orchestra/testbench": "^9.0.4",
|
||||
"overtrue/phplint": "^9.3.1",
|
||||
"php-cs-fixer/shim": "^3.57.2",
|
||||
"phpstan/phpstan": "^1.11.1",
|
||||
"phpstan/phpstan-mockery": "^1.1.2",
|
||||
"phpstan/phpstan-symfony": "^1.4.0",
|
||||
"phpunit/phpunit": "^10.5.13",
|
||||
"psr/container": "^1.1|^2.0",
|
||||
"rector/rector": "^1.1.0",
|
||||
"rector/swiss-knife": "^0.2.3",
|
||||
"symfony/config": "^7.0",
|
||||
"symfony/console": "^7.0",
|
||||
"symfony/dependency-injection": "^7.0",
|
||||
"symfony/framework-bundle": "^7.0",
|
||||
"symfony/http-kernel": "^7.0",
|
||||
"symfony/translation": "^7.0",
|
||||
"symfony/twig-bundle": "^7.0",
|
||||
"symfony/ux-twig-component": "^2.14",
|
||||
"symplify/monorepo-builder": "^11.2.20"
|
||||
"orchestra/testbench": "^9.5.2",
|
||||
"overtrue/phplint": "^9.5.3",
|
||||
"php-cs-fixer/shim": "^3.64.0",
|
||||
"phpstan/phpstan": "^1.12.7",
|
||||
"phpstan/phpstan-mockery": "^1.1.3",
|
||||
"phpstan/phpstan-phpunit": "^1.4.0",
|
||||
"phpstan/phpstan-symfony": "^1.4.10",
|
||||
"phpunit/phpunit": "^10.5.26",
|
||||
"rector/rector": "^1.2.8",
|
||||
"rector/swiss-knife": "^1.0.0",
|
||||
"symplify/monorepo-builder": "^11.2.22"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
||||
Generated
+4824
-4191
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,64 @@
|
||||
APP_NAME=Laravel
|
||||
APP_ENV=local
|
||||
APP_KEY=base64:mNtM4UEOfGE4dx7IAH4+kx4iPYPdGeu+Gaw/PIcF4II=
|
||||
APP_DEBUG=true
|
||||
APP_TIMEZONE=UTC
|
||||
APP_URL=http://localhost
|
||||
|
||||
APP_LOCALE=en
|
||||
APP_FALLBACK_LOCALE=en
|
||||
APP_FAKER_LOCALE=en_US
|
||||
|
||||
APP_MAINTENANCE_DRIVER=file
|
||||
APP_MAINTENANCE_STORE=database
|
||||
|
||||
BCRYPT_ROUNDS=12
|
||||
|
||||
LOG_CHANNEL=stack
|
||||
LOG_STACK=single
|
||||
LOG_DEPRECATIONS_CHANNEL=null
|
||||
LOG_LEVEL=debug
|
||||
|
||||
DB_CONNECTION=sqlite
|
||||
# DB_HOST=127.0.0.1
|
||||
# DB_PORT=3306
|
||||
# DB_DATABASE=laravel
|
||||
# DB_USERNAME=root
|
||||
# DB_PASSWORD=
|
||||
|
||||
SESSION_DRIVER=database
|
||||
SESSION_LIFETIME=120
|
||||
SESSION_ENCRYPT=false
|
||||
SESSION_PATH=/
|
||||
SESSION_DOMAIN=null
|
||||
|
||||
BROADCAST_CONNECTION=log
|
||||
FILESYSTEM_DISK=local
|
||||
QUEUE_CONNECTION=database
|
||||
|
||||
CACHE_STORE=database
|
||||
CACHE_PREFIX=
|
||||
|
||||
MEMCACHED_HOST=127.0.0.1
|
||||
|
||||
REDIS_CLIENT=phpredis
|
||||
REDIS_HOST=127.0.0.1
|
||||
REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
|
||||
MAIL_MAILER=log
|
||||
MAIL_HOST=127.0.0.1
|
||||
MAIL_PORT=2525
|
||||
MAIL_USERNAME=null
|
||||
MAIL_PASSWORD=null
|
||||
MAIL_ENCRYPTION=null
|
||||
MAIL_FROM_ADDRESS="hello@example.com"
|
||||
MAIL_FROM_NAME="${APP_NAME}"
|
||||
|
||||
AWS_ACCESS_KEY_ID=
|
||||
AWS_SECRET_ACCESS_KEY=
|
||||
AWS_DEFAULT_REGION=us-east-1
|
||||
AWS_BUCKET=
|
||||
AWS_USE_PATH_STYLE_ENDPOINT=false
|
||||
|
||||
VITE_APP_NAME="${APP_NAME}"
|
||||
@@ -2,10 +2,10 @@
|
||||
/node_modules
|
||||
/public/build
|
||||
/public/hot
|
||||
/public/vendor/flasher
|
||||
/public/storage
|
||||
/storage/*.key
|
||||
/vendor
|
||||
.env
|
||||
.env.backup
|
||||
.env.production
|
||||
.phpunit.result.cache
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class DashboardController extends Controller
|
||||
{
|
||||
/**
|
||||
* Show the dashboard with overview of PHPFlasher features
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
flash()->option('timeout', 10000)
|
||||
->info('Welcome to the PHPFlasher Laravel Demo! 👋 Explore different examples using the navigation.');
|
||||
|
||||
return view('dashboard');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show all notification types at once
|
||||
*/
|
||||
public function showAllTypes()
|
||||
{
|
||||
flash()->success('This is a success notification!');
|
||||
flash()->info('This is an information notification!');
|
||||
flash()->warning('This is a warning notification!');
|
||||
flash()->error('This is an error notification!');
|
||||
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show theme selector
|
||||
*/
|
||||
public function themeSelector()
|
||||
{
|
||||
return view('features.themes');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a notification with the selected theme
|
||||
*/
|
||||
public function showTheme(Request $request)
|
||||
{
|
||||
$theme = $request->input('theme', 'default');
|
||||
|
||||
flash()
|
||||
->use("theme.$theme")
|
||||
->success("This notification uses the '$theme' theme!");
|
||||
|
||||
return redirect()->route('themes');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class ExampleController extends Controller
|
||||
{
|
||||
/**
|
||||
* Form validation example
|
||||
*/
|
||||
public function formExample()
|
||||
{
|
||||
return view('examples.form');
|
||||
}
|
||||
|
||||
/**
|
||||
* Process form submission
|
||||
*/
|
||||
public function processForm(Request $request)
|
||||
{
|
||||
$validator = Validator::make($request->all(), [
|
||||
'name' => 'required|min:2|max:50',
|
||||
'email' => 'required|email',
|
||||
'subject' => 'required|min:5',
|
||||
'message' => 'required|min:10',
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
flash()->error('Please fix the errors in the form!');
|
||||
return redirect()->back()
|
||||
->withErrors($validator)
|
||||
->withInput();
|
||||
}
|
||||
|
||||
// Success scenario
|
||||
flash()
|
||||
->success('Your message has been sent successfully!')
|
||||
->option('timeout', 8000);
|
||||
|
||||
return redirect()->route('form.example');
|
||||
}
|
||||
|
||||
/**
|
||||
* AJAX example page
|
||||
*/
|
||||
public function ajaxExample()
|
||||
{
|
||||
return view('examples.ajax');
|
||||
}
|
||||
|
||||
/**
|
||||
* Process AJAX request
|
||||
*/
|
||||
public function processAjax(Request $request)
|
||||
{
|
||||
$action = $request->input('action');
|
||||
$success = rand(0, 10) > 3; // 70% success rate
|
||||
|
||||
if ($success) {
|
||||
flash()->success("The $action action was completed successfully!");
|
||||
return response()->json(['status' => 'success']);
|
||||
} else {
|
||||
flash()->error("The $action action failed. Please try again.");
|
||||
return response()->json(['status' => 'error'], 422);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Demonstrate different notification positions
|
||||
*/
|
||||
public function positionsExample()
|
||||
{
|
||||
return view('examples.positions');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show notification at specified position
|
||||
*/
|
||||
public function showAtPosition(Request $request)
|
||||
{
|
||||
$position = $request->input('position', 'top-right');
|
||||
|
||||
flash()
|
||||
->option('position', $position)
|
||||
->info("This notification appears at the '$position' position!");
|
||||
|
||||
return redirect()->route('positions.example');
|
||||
}
|
||||
|
||||
/**
|
||||
* Interactive playground to test notification options
|
||||
*/
|
||||
public function playground()
|
||||
{
|
||||
return view('examples.playground');
|
||||
}
|
||||
}
|
||||
@@ -3,16 +3,20 @@
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Foundation\Configuration\Exceptions;
|
||||
use Illuminate\Foundation\Configuration\Middleware;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
return Application::configure(basePath: dirname(__DIR__))
|
||||
->withRouting(
|
||||
web: __DIR__.'/../routes/web.php',
|
||||
commands: __DIR__.'/../routes/console.php',
|
||||
health: '/up',
|
||||
then: function () {
|
||||
Route::middleware('web')->group(base_path('routes/issues.php'));
|
||||
},
|
||||
)
|
||||
->withMiddleware(function (Middleware $middleware) {
|
||||
$middleware->web(append: [
|
||||
\App\Http\Middleware\HandleInertiaRequests::class,
|
||||
App\Http\Middleware\HandleInertiaRequests::class,
|
||||
]);
|
||||
})
|
||||
->withExceptions(function (Exceptions $exceptions) {
|
||||
|
||||
+23
-18
@@ -15,24 +15,26 @@
|
||||
],
|
||||
"require": {
|
||||
"php": "^8.2",
|
||||
"inertiajs/inertia-laravel": "^1.0",
|
||||
"laravel/framework": "^11.0",
|
||||
"laravel/tinker": "^2.9",
|
||||
"livewire/livewire": "^3.4",
|
||||
"inertiajs/inertia-laravel": "^2.0.1",
|
||||
"laravel/framework": "^12.3",
|
||||
"laravel/tinker": "^2.10.1",
|
||||
"livewire/livewire": "^3.6.2",
|
||||
"php-flasher/php-flasher": "@dev",
|
||||
"spatie/laravel-csp": "^2.9",
|
||||
"spatie/laravel-ray": "^1.36"
|
||||
"spatie/laravel-csp": "^2.10.3",
|
||||
"spatie/laravel-ray": "^1.40.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"fakerphp/faker": "^1.23",
|
||||
"larastan/larastan": "^2.9",
|
||||
"laravel/pint": "^1.13",
|
||||
"laravel/sail": "^1.26",
|
||||
"mockery/mockery": "^1.6",
|
||||
"nunomaduro/collision": "^8.0",
|
||||
"pestphp/pest": "^2.34",
|
||||
"pestphp/pest-plugin-laravel": "^2.3",
|
||||
"spatie/laravel-ignition": "^2.4"
|
||||
"barryvdh/laravel-debugbar": "^3.15.2",
|
||||
"fakerphp/faker": "^1.24.1",
|
||||
"larastan/larastan": "^3.2",
|
||||
"laravel/pint": "^1.21.2",
|
||||
"laravel/sail": "^1.41",
|
||||
"mockery/mockery": "^1.6.12",
|
||||
"nunomaduro/collision": "^8.7.0",
|
||||
"pestphp/pest": "^3.7.4",
|
||||
"pestphp/pest-plugin-laravel": "^3.1",
|
||||
"spatie/laravel-ignition": "^2.9.1",
|
||||
"spatie/ray": "^1.41.6"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
@@ -49,13 +51,16 @@
|
||||
"scripts": {
|
||||
"post-autoload-dump": [
|
||||
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
|
||||
"@php artisan package:discover --ansi"
|
||||
"@php artisan package:discover --ansi",
|
||||
"@php artisan flasher:install"
|
||||
],
|
||||
"post-update-cmd": [
|
||||
"@php artisan vendor:publish --tag=laravel-assets --ansi --force"
|
||||
"@php artisan vendor:publish --tag=laravel-assets --ansi --force",
|
||||
"@php artisan flasher:install"
|
||||
],
|
||||
"post-root-package-install": [
|
||||
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
|
||||
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\"",
|
||||
"@php artisan flasher:install"
|
||||
],
|
||||
"post-create-project-cmd": [
|
||||
"@php artisan key:generate --ansi",
|
||||
|
||||
Generated
+3596
-1591
File diff suppressed because it is too large
Load Diff
@@ -1,13 +1,64 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
declare(strict_types=1);
|
||||
|
||||
use Flasher\Prime\Configuration;
|
||||
|
||||
/*
|
||||
* Default PHPFlasher configuration for Laravel.
|
||||
*
|
||||
* This configuration file defines the default settings for PHPFlasher when
|
||||
* used within a Laravel application. It uses the Configuration class from
|
||||
* the core PHPFlasher library to establish type-safe configuration.
|
||||
*
|
||||
* @return array<string, mixed> PHPFlasher configuration
|
||||
*/
|
||||
return Configuration::from([
|
||||
// Default notification library (e.g., 'flasher', 'toastr', 'noty', 'notyf', 'sweetalert')
|
||||
'default' => 'flasher',
|
||||
|
||||
// Path to the main PHPFlasher JavaScript file
|
||||
'main_script' => '/vendor/flasher/flasher.min.js',
|
||||
|
||||
// List of CSS files to style your notifications
|
||||
'styles' => [
|
||||
'/vendor/flasher/flasher.min.css',
|
||||
],
|
||||
|
||||
// Set global options for all notifications (optional)
|
||||
// 'options' => [
|
||||
// 'timeout' => 5000, // Time in milliseconds before the notification disappears
|
||||
// 'position' => 'top-right', // Where the notification appears on the screen
|
||||
// ],
|
||||
|
||||
// Automatically inject JavaScript and CSS assets into your HTML pages
|
||||
'inject_assets' => true,
|
||||
|
||||
'options' => [
|
||||
'timeout' => 5_000,
|
||||
// Enable message translation using Laravel's translation service
|
||||
'translate' => true,
|
||||
|
||||
// URL patterns to exclude from asset injection and flash_bag conversion
|
||||
'excluded_paths' => [],
|
||||
|
||||
// Map Laravel flash message keys to notification types
|
||||
'flash_bag' => [
|
||||
'success' => ['success'],
|
||||
'error' => ['error', 'danger'],
|
||||
'warning' => ['warning', 'alarm'],
|
||||
'info' => ['info', 'notice', 'alert'],
|
||||
],
|
||||
|
||||
'flash_bag' => [
|
||||
'success' => ['success', 'ok', 'completed', 'passed', 'achieved'],
|
||||
],
|
||||
];
|
||||
// Set criteria to filter which notifications are displayed (optional)
|
||||
// 'filter' => [
|
||||
// 'limit' => 5, // Maximum number of notifications to show at once
|
||||
// ],
|
||||
|
||||
// Define notification presets to simplify notification creation (optional)
|
||||
// 'presets' => [
|
||||
// 'entity_saved' => [
|
||||
// 'type' => 'success',
|
||||
// 'title' => 'Entity saved',
|
||||
// 'message' => 'Entity saved successfully',
|
||||
// ],
|
||||
// ],
|
||||
]);
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'PHPFlasher Laravel Demo')
|
||||
|
||||
@section('content')
|
||||
<div class="max-w-7xl mx-auto">
|
||||
<div class="bg-white rounded-xl shadow-md overflow-hidden">
|
||||
<div class="p-8">
|
||||
<div class="uppercase tracking-wide text-sm text-indigo-600 font-semibold">Laravel Demo</div>
|
||||
<h2 class="mt-2 text-3xl font-extrabold tracking-tight text-gray-900">Welcome to PHPFlasher</h2>
|
||||
<p class="mt-4 text-lg text-gray-500">
|
||||
PHPFlasher is a powerful notification library for PHP applications.
|
||||
This demo shows how to use PHPFlasher in a Laravel project.
|
||||
</p>
|
||||
|
||||
<div class="mt-8 grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
|
||||
<!-- Feature Cards -->
|
||||
<div class="bg-indigo-50 p-6 rounded-lg">
|
||||
<div class="text-indigo-600 mb-2">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z" />
|
||||
</svg>
|
||||
</div>
|
||||
<h3 class="font-bold text-lg mb-2">Easy Integration</h3>
|
||||
<p class="text-gray-600">Simple API to create notifications from anywhere in your Laravel application.</p>
|
||||
</div>
|
||||
|
||||
<div class="bg-emerald-50 p-6 rounded-lg">
|
||||
<div class="text-emerald-600 mb-2">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 21a4 4 0 01-4-4V5a2 2 0 012-2h4a2 2 0 012 2v12a4 4 0 01-4 4zm0 0h12a2 2 0 002-2v-4a2 2 0 00-2-2h-2.343M11 7.343l1.657-1.657a2 2 0 012.828 0l2.829 2.829a2 2 0 010 2.828l-8.486 8.485M7 17h.01" />
|
||||
</svg>
|
||||
</div>
|
||||
<h3 class="font-bold text-lg mb-2">Multiple Themes</h3>
|
||||
<p class="text-gray-600">Choose from 15+ beautiful themes or create your own custom themes.</p>
|
||||
</div>
|
||||
|
||||
<div class="bg-amber-50 p-6 rounded-lg">
|
||||
<div class="text-amber-600 mb-2">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 5a1 1 0 011-1h14a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1V5zM4 13a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H5a1 1 0 01-1-1v-6zM16 13a1 1 0 011-1h2a1 1 0 011 1v6a1 1 0 01-1 1h-2a1 1 0 01-1-1v-6z" />
|
||||
</svg>
|
||||
</div>
|
||||
<h3 class="font-bold text-lg mb-2">Flexible Positioning</h3>
|
||||
<p class="text-gray-600">Display notifications at any corner or side of your screen.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-10">
|
||||
<h3 class="text-lg font-medium text-gray-900">Try It Now</h3>
|
||||
<div class="mt-4 flex flex-wrap gap-2">
|
||||
<a href="{{ route('all.types') }}" class="btn-primary">
|
||||
Show All Notification Types
|
||||
</a>
|
||||
<a href="{{ route('themes') }}" class="btn-outline">
|
||||
Explore Themes
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-10">
|
||||
<h3 class="text-lg font-medium text-gray-900">Code Example</h3>
|
||||
<div class="mt-4 code-block">
|
||||
<div class="code-header">
|
||||
<span>Basic Usage</span>
|
||||
</div>
|
||||
<pre><code class="language-php">// Display a success notification
|
||||
flash()->success('Item created successfully!');
|
||||
|
||||
// Display an error notification
|
||||
flash()->error('An error occurred!');
|
||||
|
||||
// Display a warning notification
|
||||
flash()->warning('Warning: This action cannot be undone.');
|
||||
|
||||
// Display an info notification
|
||||
flash()->info('The task is running in the background.');</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@@ -0,0 +1,67 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Form Example - PHPFlasher Laravel Demo')
|
||||
|
||||
@section('content')
|
||||
<div class="max-w-4xl mx-auto">
|
||||
<div class="bg-white rounded-xl shadow-md overflow-hidden">
|
||||
<div class="p-8">
|
||||
<h2 class="text-2xl font-bold text-gray-900 mb-6">Contact Form Example</h2>
|
||||
|
||||
<div class="mb-8">
|
||||
<p class="text-gray-600">
|
||||
This example demonstrates how PHPFlasher can be used to display form validation errors and success messages.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="code-block mb-8">
|
||||
<div class="code-header">
|
||||
<span>Controller Code</span>
|
||||
</div>
|
||||
<pre><code class="language-php">public function processForm(Request $request)
|
||||
{
|
||||
$validator = Validator::make($request->all(), [
|
||||
'name' => 'required|min:2|max:50',
|
||||
'email' => 'required|email',
|
||||
'subject' => 'required|min:5',
|
||||
'message' => 'required|min:10',
|
||||
]);
|
||||
|
||||
if ($validator->fails()) {
|
||||
flash()->error('Please fix the errors in the form!');
|
||||
return redirect()->back()
|
||||
->withErrors($validator)
|
||||
->withInput();
|
||||
}
|
||||
|
||||
// Success scenario
|
||||
flash()
|
||||
->success('Your message has been sent successfully!')
|
||||
->option('timeout', 8000);
|
||||
|
||||
return redirect()->route('form.example');
|
||||
}</code></pre>
|
||||
</div>
|
||||
|
||||
<form action="{{ route('form.process') }}" method="POST" class="space-y-6">
|
||||
@csrf
|
||||
|
||||
<div>
|
||||
<label for="name" class="block text-sm font-medium text-gray-700">Name</label>
|
||||
<input type="text" name="name" id="name" value="{{ old('name') }}" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500">
|
||||
@error('name')
|
||||
<p class="mt-1 text-sm text-red-600">{{ $message }}</p>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="email" class="block text-sm font-medium text-gray-700">Email</label>
|
||||
<input type="email" name="email" id="email" value="{{ old('email') }}" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500">
|
||||
@error('email')
|
||||
<p class="mt-1 text-sm text-red-600">{{ $message }}</p>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="subject" class="block text-sm font-medium text-gray-700">Subject</label>
|
||||
<input type="text" name="subject" id="subject" value="{{ old('subject
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
Route::get('/issues/190', function () {
|
||||
flash()->success('Your order has been placed successfully.');
|
||||
// Passing another success message with the view
|
||||
return redirect('/issues/190/redirect')->with('success', 'Your order will be delivered in 3-5 business days.');
|
||||
});
|
||||
|
||||
Route::get('/issues/190/redirect', function () {
|
||||
return view('welcome');
|
||||
});
|
||||
+16
-12
@@ -1,23 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Entity\Book;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
Route::get('/', function () {
|
||||
// sweetalert()->timerProgressBar()->success('hello from Home Controller');
|
||||
// noty()->layout('topCenter')->success('hello from Home Controller');
|
||||
// notyf()->ripple(false)->warning('hello from Home Controller');
|
||||
// toastr()->positionClass('toast-bottom-left')->error('hello from Home Controller');
|
||||
// flash()->use('flasher')->success('hello from flasher factory');
|
||||
|
||||
// flash()->created(new Book('lord of the rings'));
|
||||
// flash()->saved(new Book('harry potter'));
|
||||
|
||||
session()->flash('success', 'this from laravel session flash');
|
||||
|
||||
return redirect('/redirect');
|
||||
sweetalert()->timerProgressBar()->success('Your account has been successfully created!');
|
||||
noty()->layout('topCenter')->success('Welcome back, John Doe!');
|
||||
notyf()->ripple(false)->warning('Your subscription is about to expire in 3 days.');
|
||||
toastr()->positionClass('toast-bottom-left')->error('Payment failed. Please try again.');
|
||||
flash()->use('flasher')->success('Your profile has been updated successfully.');
|
||||
flash()->created(new Book('The Great Gatsby'));
|
||||
flash()->saved(new Book('1984'));
|
||||
session()->flash('success', 'Your settings have been saved.');
|
||||
return view('welcome');
|
||||
})->name('app_home');
|
||||
|
||||
Route::get('/redirect', function () {
|
||||
session()->flash('success', 'You have been redirected successfully.');
|
||||
return redirect('/destination');
|
||||
});
|
||||
|
||||
Route::get('/destination', function () {
|
||||
return view('welcome');
|
||||
});
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
||||
@@ -0,0 +1,4 @@
|
||||
--ignore-dir=vendor
|
||||
--ignore-dir=yoeunes
|
||||
--ignore-dir=node_modules
|
||||
--ignore-dir=var
|
||||
@@ -18,3 +18,7 @@
|
||||
APP_ENV=dev
|
||||
APP_SECRET=a2ee898b9e385a80ba8f7b11e97232b2
|
||||
###< symfony/framework-bundle ###
|
||||
|
||||
###> symfony/mailer ###
|
||||
MAILER_DSN=null://null
|
||||
###< symfony/mailer ###
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
/.env.*.local
|
||||
/config/secrets/prod/prod.decrypt.private.php
|
||||
/public/bundles/
|
||||
/public/vendor/flasherg
|
||||
/var/
|
||||
/vendor/
|
||||
###< symfony/framework-bundle ###
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
8.2
|
||||
@@ -0,0 +1 @@
|
||||
php=php@8.2
|
||||
+24
-17
@@ -16,19 +16,27 @@
|
||||
"php": ">=8.2",
|
||||
"ext-ctype": "*",
|
||||
"ext-iconv": "*",
|
||||
"nelmio/security-bundle": "^3.3",
|
||||
"nelmio/security-bundle": "^3.4.2",
|
||||
"php-flasher/php-flasher": "@dev",
|
||||
"phpstan/phpstan-symfony": "^1.3",
|
||||
"symfony/console": "7.0.*",
|
||||
"symfony/dotenv": "7.0.*",
|
||||
"symfony/flex": "^2",
|
||||
"symfony/framework-bundle": "7.0.*",
|
||||
"symfony/runtime": "7.0.*",
|
||||
"symfony/translation": "7.0.*",
|
||||
"symfony/twig-bundle": "7.0.*",
|
||||
"symfony/yaml": "7.0.*",
|
||||
"twig/extra-bundle": "^2.12|^3.0",
|
||||
"twig/twig": "^2.12|^3.0"
|
||||
"phpstan/phpstan-symfony": "^2.0.2",
|
||||
"symfony/console": "7.2.*",
|
||||
"symfony/dotenv": "7.2.*",
|
||||
"symfony/flex": "^2.4.7",
|
||||
"symfony/framework-bundle": "7.2.*",
|
||||
"symfony/monolog-bundle": "^3.10",
|
||||
"symfony/notifier": "7.2.*",
|
||||
"symfony/runtime": "7.2.*",
|
||||
"symfony/translation": "7.2.*",
|
||||
"symfony/twig-bundle": "7.2.*",
|
||||
"symfony/yaml": "7.2.*",
|
||||
"twig/extra-bundle": "^2.12|^3.20",
|
||||
"twig/twig": "^2.12|^3.20"
|
||||
},
|
||||
"require-dev": {
|
||||
"spatie/ray": "^1.41.5",
|
||||
"symfony/maker-bundle": "^1.62.1",
|
||||
"symfony/stopwatch": "7.2.*",
|
||||
"symfony/web-profiler-bundle": "7.2.*"
|
||||
},
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
@@ -61,7 +69,8 @@
|
||||
"scripts": {
|
||||
"auto-scripts": {
|
||||
"cache:clear": "symfony-cmd",
|
||||
"assets:install %PUBLIC_DIR%": "symfony-cmd"
|
||||
"assets:install %PUBLIC_DIR%": "symfony-cmd",
|
||||
"flasher:install": "symfony-cmd"
|
||||
},
|
||||
"post-install-cmd": [
|
||||
"@auto-scripts"
|
||||
@@ -76,10 +85,8 @@
|
||||
"extra": {
|
||||
"symfony": {
|
||||
"allow-contrib": false,
|
||||
"require": "7.0.*"
|
||||
"require": "7.2.*",
|
||||
"docker": false
|
||||
}
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/maker-bundle": "^1.58"
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+5258
-459
File diff suppressed because it is too large
Load Diff
@@ -10,5 +10,8 @@ return [
|
||||
Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
|
||||
Twig\Extra\TwigExtraBundle\TwigExtraBundle::class => ['all' => true],
|
||||
Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
|
||||
Nelmio\SecurityBundle\NelmioSecurityBundle::class => ['all' => true],
|
||||
// Nelmio\SecurityBundle\NelmioSecurityBundle::class => ['all' => true],
|
||||
Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true],
|
||||
Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
|
||||
Symfony\UX\TwigComponent\TwigComponentBundle::class => ['all' => true],
|
||||
];
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
flasher:
|
||||
# Default notification library (e.g., 'flasher', 'toastr', 'noty', etc.)
|
||||
# themes: flasher, crystal, emerald, sapphire
|
||||
default: theme.minimal
|
||||
|
||||
# Path to the main JavaScript file of PHPFlasher
|
||||
main_script: '/vendor/flasher/flasher.min.js'
|
||||
|
||||
# Path to the stylesheets for PHPFlasher notifications
|
||||
styles:
|
||||
- '/vendor/flasher/flasher.min.css'
|
||||
|
||||
# Enable translation of PHPFlasher messages using Symfony's translator service
|
||||
translate: true
|
||||
|
||||
# Automatically inject PHPFlasher assets in HTML response
|
||||
inject_assets: true
|
||||
|
||||
# Global options
|
||||
options:
|
||||
# timeout in milliseconds
|
||||
timeout: 600000
|
||||
position: 'top-right'
|
||||
|
||||
# Map Symfony session keys to PHPFlasher notification types
|
||||
flash_bag:
|
||||
success: ['success']
|
||||
error: ['error', 'danger']
|
||||
warning: ['warning', 'alarm']
|
||||
info: ['info', 'notice', 'alert']
|
||||
|
||||
# Criteria to filter displayed notifications (limit, types)
|
||||
filter:
|
||||
# Limit number of displayed notifications
|
||||
# limit: 5
|
||||
|
||||
themes:
|
||||
amazon:
|
||||
scripts:
|
||||
- '/vendor/flasher/themes/amazon/amazon.min.js'
|
||||
styles:
|
||||
- '/vendor/flasher/flasher.min.css'
|
||||
- '/vendor/flasher/themes/amazon/amazon.min.css'
|
||||
options:
|
||||
position: 'bottom-right'
|
||||
timeout: 6000
|
||||
@@ -0,0 +1,3 @@
|
||||
framework:
|
||||
mailer:
|
||||
dsn: '%env(MAILER_DSN)%'
|
||||
@@ -0,0 +1,62 @@
|
||||
monolog:
|
||||
channels:
|
||||
- deprecation # Deprecations are logged in the dedicated "deprecation" channel when it exists
|
||||
|
||||
when@dev:
|
||||
monolog:
|
||||
handlers:
|
||||
main:
|
||||
type: stream
|
||||
path: "%kernel.logs_dir%/%kernel.environment%.log"
|
||||
level: debug
|
||||
channels: ["!event"]
|
||||
# uncomment to get logging in your browser
|
||||
# you may have to allow bigger header sizes in your Web server configuration
|
||||
#firephp:
|
||||
# type: firephp
|
||||
# level: info
|
||||
#chromephp:
|
||||
# type: chromephp
|
||||
# level: info
|
||||
console:
|
||||
type: console
|
||||
process_psr_3_messages: false
|
||||
channels: ["!event", "!doctrine", "!console"]
|
||||
|
||||
when@test:
|
||||
monolog:
|
||||
handlers:
|
||||
main:
|
||||
type: fingers_crossed
|
||||
action_level: error
|
||||
handler: nested
|
||||
excluded_http_codes: [404, 405]
|
||||
channels: ["!event"]
|
||||
nested:
|
||||
type: stream
|
||||
path: "%kernel.logs_dir%/%kernel.environment%.log"
|
||||
level: debug
|
||||
|
||||
when@prod:
|
||||
monolog:
|
||||
handlers:
|
||||
main:
|
||||
type: fingers_crossed
|
||||
action_level: error
|
||||
handler: nested
|
||||
excluded_http_codes: [404, 405]
|
||||
buffer_size: 50 # How many messages should be saved? Prevent memory leaks
|
||||
nested:
|
||||
type: stream
|
||||
path: php://stderr
|
||||
level: debug
|
||||
formatter: monolog.formatter.json
|
||||
console:
|
||||
type: console
|
||||
process_psr_3_messages: false
|
||||
channels: ["!event", "!doctrine"]
|
||||
deprecation:
|
||||
type: stream
|
||||
channels: [deprecation]
|
||||
path: php://stderr
|
||||
formatter: monolog.formatter.json
|
||||
@@ -1,33 +1,33 @@
|
||||
nelmio_security:
|
||||
# prevents framing of the entire site
|
||||
clickjacking:
|
||||
paths:
|
||||
'^/.*': DENY
|
||||
|
||||
# disables content type sniffing for script resources
|
||||
content_type:
|
||||
nosniff: true
|
||||
|
||||
# forces Microsoft's XSS-Protection with
|
||||
# its block mode
|
||||
xss_protection:
|
||||
enabled: true
|
||||
mode_block: true
|
||||
|
||||
# Send a full URL in the `Referer` header when performing a same-origin request,
|
||||
# only send the origin of the document to secure destination (HTTPS->HTTPS),
|
||||
# and send no header to a less secure destination (HTTPS->HTTP).
|
||||
# If `strict-origin-when-cross-origin` is not supported, use `no-referrer` policy,
|
||||
# no referrer information is sent along with requests.
|
||||
referrer_policy:
|
||||
enabled: true
|
||||
policies:
|
||||
- 'no-referrer'
|
||||
- 'strict-origin-when-cross-origin'
|
||||
|
||||
csp:
|
||||
enabled: true
|
||||
|
||||
enforce:
|
||||
script-src:
|
||||
- 'self'
|
||||
# nelmio_security:
|
||||
# # prevents framing of the entire site
|
||||
# clickjacking:
|
||||
# paths:
|
||||
# '^/.*': DENY
|
||||
#
|
||||
# # disables content type sniffing for script resources
|
||||
# content_type:
|
||||
# nosniff: true
|
||||
#
|
||||
# # forces Microsoft's XSS-Protection with
|
||||
# # its block mode
|
||||
# xss_protection:
|
||||
# enabled: true
|
||||
# mode_block: true
|
||||
#
|
||||
# # Send a full URL in the `Referer` header when performing a same-origin request,
|
||||
# # only send the origin of the document to secure destination (HTTPS->HTTPS),
|
||||
# # and send no header to a less secure destination (HTTPS->HTTP).
|
||||
# # If `strict-origin-when-cross-origin` is not supported, use `no-referrer` policy,
|
||||
# # no referrer information is sent along with requests.
|
||||
# referrer_policy:
|
||||
# enabled: true
|
||||
# policies:
|
||||
# - 'no-referrer'
|
||||
# - 'strict-origin-when-cross-origin'
|
||||
#
|
||||
# csp:
|
||||
# enabled: true
|
||||
#
|
||||
# enforce:
|
||||
# script-src:
|
||||
# - 'self'
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
framework:
|
||||
notifier:
|
||||
chatter_transports:
|
||||
texter_transports:
|
||||
channel_policy:
|
||||
# use chat/slack, chat/telegram, sms/twilio or sms/nexmo
|
||||
urgent: ['email']
|
||||
high: ['email']
|
||||
medium: ['email']
|
||||
low: ['email']
|
||||
admin_recipients:
|
||||
- { email: admin@example.com }
|
||||
@@ -0,0 +1,5 @@
|
||||
twig_component:
|
||||
anonymous_template_directory: 'components/'
|
||||
defaults:
|
||||
# Namespace & directory for components
|
||||
App\Twig\Components\: 'components/'
|
||||
@@ -0,0 +1,17 @@
|
||||
when@dev:
|
||||
web_profiler:
|
||||
toolbar: false
|
||||
intercept_redirects: false
|
||||
|
||||
framework:
|
||||
profiler:
|
||||
only_exceptions: false
|
||||
collect_serializer_data: true
|
||||
|
||||
when@test:
|
||||
web_profiler:
|
||||
toolbar: false
|
||||
intercept_redirects: false
|
||||
|
||||
framework:
|
||||
profiler: { collect: false }
|
||||
@@ -0,0 +1,8 @@
|
||||
when@dev:
|
||||
web_profiler_wdt:
|
||||
resource: '@WebProfilerBundle/Resources/config/routing/wdt.xml'
|
||||
prefix: /_wdt
|
||||
|
||||
web_profiler_profiler:
|
||||
resource: '@WebProfilerBundle/Resources/config/routing/profiler.xml'
|
||||
prefix: /_profiler
|
||||
@@ -0,0 +1,22 @@
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const demoForm = document.getElementById('notification-demo-form');
|
||||
|
||||
if (demoForm) {
|
||||
demoForm.addEventListener('submit', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const type = document.getElementById('notification-type').value;
|
||||
const title = document.getElementById('notification-title').value;
|
||||
const message = document.getElementById('notification-message').value;
|
||||
const position = document.getElementById('notification-position').value;
|
||||
const timeout = document.getElementById('notification-timeout').value;
|
||||
|
||||
// Use the PHPFlasher JavaScript API to show the notification
|
||||
window.flasher[type](message, {
|
||||
title: title,
|
||||
position: position,
|
||||
timeout: parseInt(timeout, 10)
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1 @@
|
||||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("@flasher/flasher"),require("noty")):"function"==typeof define&&define.amd?define(["@flasher/flasher","noty"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).Noty=t(e.flasher,e.Noty)}(this,(function(e,t){"use strict";class s{success(e,t,s){this.flash("success",e,t,s)}error(e,t,s){this.flash("error",e,t,s)}info(e,t,s){this.flash("info",e,t,s)}warning(e,t,s){this.flash("warning",e,t,s)}flash(e,t,s,o){let i,n,r,l={};if("object"==typeof e?(l=Object.assign({},e),i=l.type,n=l.message,r=l.title,delete l.type,delete l.message,delete l.title):"object"==typeof t?(l=Object.assign({},t),i=e,n=l.message,r=l.title,delete l.message,delete l.title):(i=e,n=t,null==s?(r=void 0,l=o||{}):"string"==typeof s?(r=s,l=o||{}):"object"==typeof s&&(l=Object.assign({},s),"title"in l?(r=l.title,delete l.title):r=void 0,o&&"object"==typeof o&&(l=Object.assign(Object.assign({},l),o)))),!i)throw new Error("Type is required for notifications");if(null==n)throw new Error("Message is required for notifications");null==r&&(r=i.charAt(0).toUpperCase()+i.slice(1));const a={type:i,message:n,title:r,options:l,metadata:{plugin:""}};this.renderOptions({}),this.renderEnvelopes([a])}}const o=new class extends s{constructor(){super(...arguments),this.defaultOptions={timeout:1e4}}renderEnvelopes(e){(null==e?void 0:e.length)&&e.forEach((e=>{try{const s=Object.assign({text:e.message,type:e.type},this.defaultOptions);e.options&&Object.assign(s,e.options);const o=new t(s);o.show();const i=o.layoutDom;i&&"object"==typeof i.dataset&&(i.dataset.turboTemporary="")}catch(t){console.error("PHPFlasher Noty: Error rendering notification",t,e)}}))}renderOptions(e){e&&(Object.assign(this.defaultOptions,e),t.overrideDefaults(this.defaultOptions))}};return e.addPlugin("noty",o),o}));
|
||||
@@ -0,0 +1,2 @@
|
||||
.notyf__icon--info,.notyf__icon--warning{background:#fff;border-radius:50%;box-sizing:border-box;display:block;height:1em;margin:0 auto;position:relative;width:1em}.notyf__icon--info:after,.notyf__icon--info:before,.notyf__icon--warning:after,.notyf__icon--warning:before{border-width:0;box-sizing:border-box;content:"";position:absolute;transition:all 1s}.notyf__icon--info:after,.notyf__icon--info:before{background-color:currentcolor;border-radius:.03em;left:50%;transform:translateX(-50%);width:.15em}.notyf__icon--info:before{height:.38em;top:.4em}.notyf__icon--info:after{box-shadow:-.06em .19em,-.06em .44em,.06em .44em;height:.13em;top:.21em}.notyf__icon--warning:after,.notyf__icon--warning:before{background-color:currentcolor;border-radius:.03em;left:50%;transform:translateX(-50%);width:.15em}.notyf__icon--warning:before{height:.38em;top:.21em}.notyf__icon--warning:after{height:.13em;top:.65em}
|
||||
@keyframes notyf-fadeinup{0%{opacity:0;transform:translateY(25%)}to{opacity:1;transform:translateY(0)}}@keyframes notyf-fadeinleft{0%{opacity:0;transform:translateX(25%)}to{opacity:1;transform:translateX(0)}}@keyframes notyf-fadeoutright{0%{opacity:1;transform:translateX(0)}to{opacity:0;transform:translateX(25%)}}@keyframes notyf-fadeoutdown{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(25%)}}@keyframes ripple{0%{transform:scale(0) translateY(-45%) translateX(13%)}to{transform:scale(1) translateY(-45%) translateX(13%)}}.notyf{align-items:flex-end;box-sizing:border-box;color:#fff;display:flex;flex-direction:column;height:100%;justify-content:flex-end;left:0;padding:20px;pointer-events:none;position:fixed;top:0;width:100%;z-index:9999}.notyf__icon--error,.notyf__icon--success{background:#fff;border-radius:50%;display:block;height:21px;margin:0 auto;position:relative;width:21px}.notyf__icon--error:after,.notyf__icon--error:before{background:currentColor;border-radius:3px;content:"";display:block;height:12px;left:9px;position:absolute;top:5px;width:3px}.notyf__icon--error:after{transform:rotate(-45deg)}.notyf__icon--error:before{transform:rotate(45deg)}.notyf__icon--success:after,.notyf__icon--success:before{background:currentColor;border-radius:3px;content:"";display:block;position:absolute;width:3px}.notyf__icon--success:after{height:6px;left:6px;top:9px;transform:rotate(-45deg)}.notyf__icon--success:before{height:11px;left:10px;top:5px;transform:rotate(45deg)}.notyf__toast{animation:notyf-fadeinup .3s ease-in forwards;border-radius:2px;box-shadow:0 3px 7px 0 rgba(0,0,0,.25);box-sizing:border-box;display:block;flex-shrink:0;max-width:300px;overflow:hidden;padding:0 15px;pointer-events:auto;position:relative;transform:translateY(25%)}.notyf__toast--disappear{animation:notyf-fadeoutdown .3s forwards;animation-delay:.25s;transform:translateY(0)}.notyf__toast--disappear .notyf__icon,.notyf__toast--disappear .notyf__message{animation:notyf-fadeoutdown .3s forwards;opacity:1;transform:translateY(0)}.notyf__toast--disappear .notyf__dismiss{animation:notyf-fadeoutright .3s forwards;opacity:1;transform:translateX(0)}.notyf__toast--disappear .notyf__message{animation-delay:.05s}.notyf__toast--upper{margin-bottom:20px}.notyf__toast--lower{margin-top:20px}.notyf__toast--dismissible .notyf__wrapper{padding-right:30px}.notyf__ripple{animation:ripple .4s ease-out forwards;border-radius:50%;height:400px;position:absolute;right:0;top:0;transform:scale(0) translateY(-51%) translateX(13%);transform-origin:bottom right;width:400px;z-index:5}.notyf__wrapper{align-items:center;border-radius:3px;display:flex;padding-bottom:17px;padding-right:15px;padding-top:17px;position:relative;z-index:10}.notyf__icon{animation:notyf-fadeinup .3s forwards;animation-delay:.3s;font-size:1.3em;margin-right:13px;opacity:0;text-align:center;width:22px}.notyf__dismiss{animation:notyf-fadeinleft .3s forwards;animation-delay:.35s;height:100%;margin-right:-15px;opacity:0;position:absolute;right:0;top:0;width:26px}.notyf__dismiss-btn{background-color:rgba(0,0,0,.25);border:none;cursor:pointer;height:100%;opacity:.35;outline:none;transition:opacity .2s ease,background-color .2s ease;width:100%}.notyf__dismiss-btn:after,.notyf__dismiss-btn:before{background:#fff;border-radius:3px;content:"";height:12px;left:calc(50% - 1px);position:absolute;top:calc(50% - 5px);width:2px}.notyf__dismiss-btn:after{transform:rotate(-45deg)}.notyf__dismiss-btn:before{transform:rotate(45deg)}.notyf__dismiss-btn:hover{background-color:rgba(0,0,0,.15);opacity:.7}.notyf__dismiss-btn:active{opacity:.8}.notyf__message{animation:notyf-fadeinup .3s forwards;animation-delay:.25s;line-height:1.5em;opacity:0;position:relative;vertical-align:middle}@media only screen and (max-width:480px){.notyf{padding:0}.notyf__ripple{animation-duration:.5s;height:600px;width:600px}.notyf__toast{border-radius:0;box-shadow:0 -2px 7px 0 rgba(0,0,0,.13);max-width:none;width:100%}.notyf__dismiss{width:56px}}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("@flasher/flasher"),require("sweetalert2")):"function"==typeof define&&define.amd?define(["@flasher/flasher","sweetalert2"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).sweetalert=t(e.flasher,e.Swal)}(this,(function(e,t){"use strict";function r(e,t,r,s){return new(r||(r=Promise))((function(i,n){function o(e){try{a(s.next(e))}catch(e){n(e)}}function l(e){try{a(s.throw(e))}catch(e){n(e)}}function a(e){var t;e.done?i(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(o,l)}a((s=s.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;class s{success(e,t,r){this.flash("success",e,t,r)}error(e,t,r){this.flash("error",e,t,r)}info(e,t,r){this.flash("info",e,t,r)}warning(e,t,r){this.flash("warning",e,t,r)}flash(e,t,r,s){let i,n,o,l={};if("object"==typeof e?(l=Object.assign({},e),i=l.type,n=l.message,o=l.title,delete l.type,delete l.message,delete l.title):"object"==typeof t?(l=Object.assign({},t),i=e,n=l.message,o=l.title,delete l.message,delete l.title):(i=e,n=t,null==r?(o=void 0,l=s||{}):"string"==typeof r?(o=r,l=s||{}):"object"==typeof r&&(l=Object.assign({},r),"title"in l?(o=l.title,delete l.title):o=void 0,s&&"object"==typeof s&&(l=Object.assign(Object.assign({},l),s)))),!i)throw new Error("Type is required for notifications");if(null==n)throw new Error("Message is required for notifications");null==o&&(o=i.charAt(0).toUpperCase()+i.slice(1));const a={type:i,message:n,title:o,options:l,metadata:{plugin:""}};this.renderOptions({}),this.renderEnvelopes([a])}}const i=new class extends s{renderEnvelopes(e){return r(this,void 0,void 0,(function*(){this.sweetalert||this.initializeSweetAlert();try{for(const t of e)yield this.renderEnvelope(t)}catch(e){console.error("PHPFlasher SweetAlert: Error rendering envelopes",e)}}))}renderOptions(e){try{this.sweetalert=this.sweetalert||t.mixin(Object.assign({timer:e.timer||1e4,timerProgressBar:e.timerProgressBar||!0},e)),this.setupTurboCompatibility()}catch(e){console.error("PHPFlasher SweetAlert: Error applying options",e)}}renderEnvelope(e){return r(this,void 0,void 0,(function*(){var t;try{let{options:r}=e;r=Object.assign(Object.assign({},r),{icon:(null==r?void 0:r.icon)||e.type,text:(null==r?void 0:r.text)||e.message});const s=yield null===(t=this.sweetalert)||void 0===t?void 0:t.fire(r);this.dispatchResultEvent(s,e)}catch(t){console.error("PHPFlasher SweetAlert: Error rendering envelope",t,e)}}))}initializeSweetAlert(){this.sweetalert||this.renderOptions({timer:1e4,timerProgressBar:!0})}setupTurboCompatibility(){document.addEventListener("turbo:before-cache",(()=>{if(t.isVisible()){const e=t.getPopup();e&&e.style.setProperty("animation-duration","0ms"),t.close()}}))}dispatchResultEvent(e,t){e&&window.dispatchEvent(new CustomEvent("flasher:sweetalert:promise",{detail:{promise:e,envelope:t}}))}};return e.addPlugin("sweetalert",i),i}));
|
||||
@@ -0,0 +1 @@
|
||||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("@flasher/flasher"),require("toastr")):"function"==typeof define&&define.amd?define(["@flasher/flasher","toastr"],t):(e="undefined"!=typeof globalThis?globalThis:e||self).toastr=t(e.flasher,e.toastr)}(this,(function(e,t){"use strict";class s{success(e,t,s){this.flash("success",e,t,s)}error(e,t,s){this.flash("error",e,t,s)}info(e,t,s){this.flash("info",e,t,s)}warning(e,t,s){this.flash("warning",e,t,s)}flash(e,t,s,r){let o,i,n,a={};if("object"==typeof e?(a=Object.assign({},e),o=a.type,i=a.message,n=a.title,delete a.type,delete a.message,delete a.title):"object"==typeof t?(a=Object.assign({},t),o=e,i=a.message,n=a.title,delete a.message,delete a.title):(o=e,i=t,null==s?(n=void 0,a=r||{}):"string"==typeof s?(n=s,a=r||{}):"object"==typeof s&&(a=Object.assign({},s),"title"in a?(n=a.title,delete a.title):n=void 0,r&&"object"==typeof r&&(a=Object.assign(Object.assign({},a),r)))),!o)throw new Error("Type is required for notifications");if(null==i)throw new Error("Message is required for notifications");null==n&&(n=o.charAt(0).toUpperCase()+o.slice(1));const l={type:o,message:i,title:n,options:a,metadata:{plugin:""}};this.renderOptions({}),this.renderEnvelopes([l])}}const r=new class extends s{renderEnvelopes(e){(null==e?void 0:e.length)&&this.isDependencyAvailable()&&e.forEach((e=>{try{const{message:s,title:r,type:o,options:i}=e,n=t[o](s,r,i);if(n&&n.parent)try{const e=n.parent();e&&"function"==typeof e.attr&&e.attr("data-turbo-temporary","")}catch(e){console.error("PHPFlasher Toastr: Error setting Turbo compatibility",e)}}catch(t){console.error("PHPFlasher Toastr: Error rendering notification",t,e)}}))}renderOptions(e){if(this.isDependencyAvailable())try{t.options=Object.assign({timeOut:e.timeOut||1e4,progressBar:e.progressBar||!0},e)}catch(e){console.error("PHPFlasher Toastr: Error applying options",e)}}isDependencyAvailable(){return!(!window.jQuery&&!window.$)||(console.error("PHPFlasher Toastr: jQuery is required but not loaded. Make sure jQuery is loaded before using Toastr."),!1)}};return e.addPlugin("toastr",r),r}));
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"/vendor/flasher/flasher.min.js": "/vendor/flasher/flasher.min.js?id=2dfca2b3c2159f2ff676a62ad338f092",
|
||||
"/vendor/flasher/flasher.min.css": "/vendor/flasher/flasher.min.css?id=689710919ac658a64bacd98998f04534",
|
||||
"/vendor/flasher/themes/amazon/amazon.min.css": "/vendor/flasher/themes/amazon/amazon.min.css?id=9ee70f25ed683a1a06c96832e53ae372",
|
||||
"/vendor/flasher/themes/amazon/amazon.min.js": "/vendor/flasher/themes/amazon/amazon.min.js?id=2e8cbc1a93524a122b8f62f072f2ff71",
|
||||
"/vendor/flasher/themes/sapphire/sapphire.min.css": "/vendor/flasher/themes/sapphire/sapphire.min.css?id=f7b4efc7b645ee792dacd4438fdc4ea3",
|
||||
"/vendor/flasher/themes/sapphire/sapphire.min.js": "/vendor/flasher/themes/sapphire/sapphire.min.js?id=aeaeda5a1eadd052f0c466fdf6c6f7b3",
|
||||
"/vendor/flasher/themes/google/google.min.js": "/vendor/flasher/themes/google/google.min.js?id=812cddda9e58967cd46fb1f5a385b8ec",
|
||||
"/vendor/flasher/themes/google/google.min.css": "/vendor/flasher/themes/google/google.min.css?id=b5f06fb2a4795ce361e94113d3b91822",
|
||||
"/vendor/flasher/themes/flasher/flasher.min.js": "/vendor/flasher/themes/flasher/flasher.min.js?id=7b56b75dafcf90e2fd3cf243f6e17ede",
|
||||
"/vendor/flasher/themes/flasher/flasher.min.css": "/vendor/flasher/themes/flasher/flasher.min.css?id=a806450943da43e7876dd3ddf78c47bc",
|
||||
"/vendor/flasher/themes/aurora/aurora.min.css": "/vendor/flasher/themes/aurora/aurora.min.css?id=c147c3dce846ce387a2360fb7c5ef317",
|
||||
"/vendor/flasher/themes/aurora/aurora.min.js": "/vendor/flasher/themes/aurora/aurora.min.js?id=16817691e8c76e7a27ea1be3a9d3e288",
|
||||
"/vendor/flasher/themes/crystal/crystal.min.css": "/vendor/flasher/themes/crystal/crystal.min.css?id=22d1ac60ba71b99d33f06d8860542bea",
|
||||
"/vendor/flasher/themes/crystal/crystal.min.js": "/vendor/flasher/themes/crystal/crystal.min.js?id=b98d586c16df24f556bd509d128d4206",
|
||||
"/vendor/flasher/themes/minimal/minimal.min.css": "/vendor/flasher/themes/minimal/minimal.min.css?id=ece6c8d8425a37426f2953e7d771cd34",
|
||||
"/vendor/flasher/themes/minimal/minimal.min.js": "/vendor/flasher/themes/minimal/minimal.min.js?id=1497c70c9875d728c439136c92fbca08",
|
||||
"/vendor/flasher/themes/ios/ios.min.js": "/vendor/flasher/themes/ios/ios.min.js?id=7149c00236bda6f7aecfd7f0ce18a1f4",
|
||||
"/vendor/flasher/themes/ios/ios.min.css": "/vendor/flasher/themes/ios/ios.min.css?id=9680ce2ce92ac435c99a40e599d2e775",
|
||||
"/vendor/flasher/themes/onyx/onyx.min.css": "/vendor/flasher/themes/onyx/onyx.min.css?id=eff8e7447767c39298a9c3565a917d79",
|
||||
"/vendor/flasher/themes/onyx/onyx.min.js": "/vendor/flasher/themes/onyx/onyx.min.js?id=2c8dc59c4abefd370535eb102d4e6711",
|
||||
"/vendor/flasher/themes/amber/amber.min.js": "/vendor/flasher/themes/amber/amber.min.js?id=95b57e413d5cb896b47ad9158dd4ef07",
|
||||
"/vendor/flasher/themes/amber/amber.min.css": "/vendor/flasher/themes/amber/amber.min.css?id=20aa374b7ede682a6a0eb00c19a0013c",
|
||||
"/vendor/flasher/themes/facebook/facebook.min.js": "/vendor/flasher/themes/facebook/facebook.min.js?id=7ce0a41e3886db70a56b6e9e49bdda91",
|
||||
"/vendor/flasher/themes/facebook/facebook.min.css": "/vendor/flasher/themes/facebook/facebook.min.css?id=edfbad59ded6831073a0d08a799757fd",
|
||||
"/vendor/flasher/themes/neon/neon.min.css": "/vendor/flasher/themes/neon/neon.min.css?id=38716f3f934f720ac34fb6617d5dc674",
|
||||
"/vendor/flasher/themes/neon/neon.min.js": "/vendor/flasher/themes/neon/neon.min.js?id=01987a2d265f63b2e92fe5f3e4b61496",
|
||||
"/vendor/flasher/themes/slack/slack.min.js": "/vendor/flasher/themes/slack/slack.min.js?id=6b1ade06f3eb351e9eaef76d402918fb",
|
||||
"/vendor/flasher/themes/slack/slack.min.css": "/vendor/flasher/themes/slack/slack.min.css?id=4fa1fe1bdca7c256f225e9f4c2e6d779",
|
||||
"/vendor/flasher/themes/jade/jade.min.js": "/vendor/flasher/themes/jade/jade.min.js?id=0fbcab9da8649325269c934da21006cc",
|
||||
"/vendor/flasher/themes/jade/jade.min.css": "/vendor/flasher/themes/jade/jade.min.css?id=b140ea3056bc6eaa860c891bedf16818",
|
||||
"/vendor/flasher/themes/material/material.min.js": "/vendor/flasher/themes/material/material.min.js?id=0360045692aaa32af12dc9739374fdae",
|
||||
"/vendor/flasher/themes/material/material.min.css": "/vendor/flasher/themes/material/material.min.css?id=f0327e5645332c10d957fff6af1220fc",
|
||||
"/vendor/flasher/themes/ruby/ruby.min.css": "/vendor/flasher/themes/ruby/ruby.min.css?id=faffa15686ab77a5f8988d1b8cc54650",
|
||||
"/vendor/flasher/themes/ruby/ruby.min.js": "/vendor/flasher/themes/ruby/ruby.min.js?id=7c8e19091329bd9242408f8d5b9890e7",
|
||||
"/vendor/flasher/themes/emerald/emerald.min.css": "/vendor/flasher/themes/emerald/emerald.min.css?id=4e346793d433693b3fdfd9de46d05590",
|
||||
"/vendor/flasher/themes/emerald/emerald.min.js": "/vendor/flasher/themes/emerald/emerald.min.js?id=815113a3e5023948b5f700f5d62253dd",
|
||||
"/vendor/flasher/mint.css": "/vendor/flasher/mint.css?id=348f135fff639305dde0005c647c1d20",
|
||||
"/vendor/flasher/flasher-noty.min.js": "/vendor/flasher/flasher-noty.min.js?id=4a788f294fa818764ee4d3e1cf10a330",
|
||||
"/vendor/flasher/noty.css": "/vendor/flasher/noty.css?id=bf51111a785e04cc8c86a7786e855484",
|
||||
"/vendor/flasher/noty.min.js": "/vendor/flasher/noty.min.js?id=840a31ddb720ff391cfc386c009d3422",
|
||||
"/vendor/flasher/flasher-notyf.min.js": "/vendor/flasher/flasher-notyf.min.js?id=d6c390269f18e78bc9c74a98fc6c3c29",
|
||||
"/vendor/flasher/flasher-notyf.min.css": "/vendor/flasher/flasher-notyf.min.css?id=a68d410be6df5aaa1dd8ed3a2798d390",
|
||||
"/vendor/flasher/toastr.min.css": "/vendor/flasher/toastr.min.css?id=f284028c678041d687c6f1be6968f68a",
|
||||
"/vendor/flasher/flasher-toastr.min.js": "/vendor/flasher/flasher-toastr.min.js?id=1ba7dae06e6524905228794c1db14290",
|
||||
"/vendor/flasher/toastr.min.js": "/vendor/flasher/toastr.min.js?id=8ee1218b09fb02d43fcf0b84e30637ad",
|
||||
"/vendor/flasher/jquery.min.js": "/vendor/flasher/jquery.min.js?id=2c872dbe60f4ba70fb85356113d8b35e",
|
||||
"/vendor/flasher/sweetalert2.min.js": "/vendor/flasher/sweetalert2.min.js?id=bba3afcfe7dcc339fa25fad49842c2bf",
|
||||
"/vendor/flasher/sweetalert2.min.css": "/vendor/flasher/sweetalert2.min.css?id=83b54381abbed7676c22f411eba2c61d",
|
||||
"/vendor/flasher/flasher-sweetalert.min.js": "/vendor/flasher/flasher-sweetalert.min.js?id=471a0b1aec6d6adc8e42a7c5dfcf0a93"
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
.noty_theme__mint.noty_bar {
|
||||
margin: 4px 0;
|
||||
overflow: hidden;
|
||||
border-radius: 2px;
|
||||
position: relative; }
|
||||
.noty_theme__mint.noty_bar .noty_body {
|
||||
padding: 10px;
|
||||
font-size: 14px; }
|
||||
.noty_theme__mint.noty_bar .noty_buttons {
|
||||
padding: 10px; }
|
||||
|
||||
.noty_theme__mint.noty_type__alert,
|
||||
.noty_theme__mint.noty_type__notification {
|
||||
background-color: #fff;
|
||||
border-bottom: 1px solid #D1D1D1;
|
||||
color: #2F2F2F; }
|
||||
|
||||
.noty_theme__mint.noty_type__warning {
|
||||
background-color: #FFAE42;
|
||||
border-bottom: 1px solid #E89F3C;
|
||||
color: #fff; }
|
||||
|
||||
.noty_theme__mint.noty_type__error {
|
||||
background-color: #DE636F;
|
||||
border-bottom: 1px solid #CA5A65;
|
||||
color: #fff; }
|
||||
|
||||
.noty_theme__mint.noty_type__info,
|
||||
.noty_theme__mint.noty_type__information {
|
||||
background-color: #7F7EFF;
|
||||
border-bottom: 1px solid #7473E8;
|
||||
color: #fff; }
|
||||
|
||||
.noty_theme__mint.noty_type__success {
|
||||
background-color: #AFC765;
|
||||
border-bottom: 1px solid #A0B55C;
|
||||
color: #fff; }
|
||||
+216
@@ -0,0 +1,216 @@
|
||||
.noty_layout_mixin, #noty_layout__top, #noty_layout__topLeft, #noty_layout__topCenter, #noty_layout__topRight, #noty_layout__bottom, #noty_layout__bottomLeft, #noty_layout__bottomCenter, #noty_layout__bottomRight, #noty_layout__center, #noty_layout__centerLeft, #noty_layout__centerRight {
|
||||
position: fixed;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
z-index: 9999999;
|
||||
-webkit-transform: translateZ(0) scale(1, 1);
|
||||
transform: translateZ(0) scale(1, 1);
|
||||
-webkit-backface-visibility: hidden;
|
||||
backface-visibility: hidden;
|
||||
-webkit-font-smoothing: subpixel-antialiased;
|
||||
filter: blur(0);
|
||||
-webkit-filter: blur(0);
|
||||
max-width: 90%; }
|
||||
|
||||
#noty_layout__top {
|
||||
top: 0;
|
||||
left: 5%;
|
||||
width: 90%; }
|
||||
|
||||
#noty_layout__topLeft {
|
||||
top: 20px;
|
||||
left: 20px;
|
||||
width: 325px; }
|
||||
|
||||
#noty_layout__topCenter {
|
||||
top: 5%;
|
||||
left: 50%;
|
||||
width: 325px;
|
||||
-webkit-transform: translate(-webkit-calc(-50% - .5px)) translateZ(0) scale(1, 1);
|
||||
transform: translate(calc(-50% - .5px)) translateZ(0) scale(1, 1); }
|
||||
|
||||
#noty_layout__topRight {
|
||||
top: 20px;
|
||||
right: 20px;
|
||||
width: 325px; }
|
||||
|
||||
#noty_layout__bottom {
|
||||
bottom: 0;
|
||||
left: 5%;
|
||||
width: 90%; }
|
||||
|
||||
#noty_layout__bottomLeft {
|
||||
bottom: 20px;
|
||||
left: 20px;
|
||||
width: 325px; }
|
||||
|
||||
#noty_layout__bottomCenter {
|
||||
bottom: 5%;
|
||||
left: 50%;
|
||||
width: 325px;
|
||||
-webkit-transform: translate(-webkit-calc(-50% - .5px)) translateZ(0) scale(1, 1);
|
||||
transform: translate(calc(-50% - .5px)) translateZ(0) scale(1, 1); }
|
||||
|
||||
#noty_layout__bottomRight {
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
width: 325px; }
|
||||
|
||||
#noty_layout__center {
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 325px;
|
||||
-webkit-transform: translate(-webkit-calc(-50% - .5px), -webkit-calc(-50% - .5px)) translateZ(0) scale(1, 1);
|
||||
transform: translate(calc(-50% - .5px), calc(-50% - .5px)) translateZ(0) scale(1, 1); }
|
||||
|
||||
#noty_layout__centerLeft {
|
||||
top: 50%;
|
||||
left: 20px;
|
||||
width: 325px;
|
||||
-webkit-transform: translate(0, -webkit-calc(-50% - .5px)) translateZ(0) scale(1, 1);
|
||||
transform: translate(0, calc(-50% - .5px)) translateZ(0) scale(1, 1); }
|
||||
|
||||
#noty_layout__centerRight {
|
||||
top: 50%;
|
||||
right: 20px;
|
||||
width: 325px;
|
||||
-webkit-transform: translate(0, -webkit-calc(-50% - .5px)) translateZ(0) scale(1, 1);
|
||||
transform: translate(0, calc(-50% - .5px)) translateZ(0) scale(1, 1); }
|
||||
|
||||
.noty_progressbar {
|
||||
display: none; }
|
||||
|
||||
.noty_has_timeout.noty_has_progressbar .noty_progressbar {
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
height: 3px;
|
||||
width: 100%;
|
||||
background-color: #646464;
|
||||
opacity: 0.2;
|
||||
filter: alpha(opacity=10); }
|
||||
|
||||
.noty_bar {
|
||||
-webkit-backface-visibility: hidden;
|
||||
-webkit-transform: translate(0, 0) translateZ(0) scale(1, 1);
|
||||
-ms-transform: translate(0, 0) scale(1, 1);
|
||||
transform: translate(0, 0) scale(1, 1);
|
||||
-webkit-font-smoothing: subpixel-antialiased;
|
||||
overflow: hidden; }
|
||||
|
||||
.noty_effects_open {
|
||||
opacity: 0;
|
||||
-webkit-transform: translate(50%);
|
||||
-ms-transform: translate(50%);
|
||||
transform: translate(50%);
|
||||
-webkit-animation: noty_anim_in 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55);
|
||||
animation: noty_anim_in 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55);
|
||||
-webkit-animation-fill-mode: forwards;
|
||||
animation-fill-mode: forwards; }
|
||||
|
||||
.noty_effects_close {
|
||||
-webkit-animation: noty_anim_out 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55);
|
||||
animation: noty_anim_out 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55);
|
||||
-webkit-animation-fill-mode: forwards;
|
||||
animation-fill-mode: forwards; }
|
||||
|
||||
.noty_fix_effects_height {
|
||||
-webkit-animation: noty_anim_height 75ms ease-out;
|
||||
animation: noty_anim_height 75ms ease-out; }
|
||||
|
||||
.noty_close_with_click {
|
||||
cursor: pointer; }
|
||||
|
||||
.noty_close_button {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
right: 2px;
|
||||
font-weight: bold;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
text-align: center;
|
||||
line-height: 20px;
|
||||
background-color: rgba(0, 0, 0, 0.05);
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
-webkit-transition: all .2s ease-out;
|
||||
transition: all .2s ease-out; }
|
||||
|
||||
.noty_close_button:hover {
|
||||
background-color: rgba(0, 0, 0, 0.1); }
|
||||
|
||||
.noty_modal {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #000;
|
||||
z-index: 10000;
|
||||
opacity: .3;
|
||||
left: 0;
|
||||
top: 0; }
|
||||
|
||||
.noty_modal.noty_modal_open {
|
||||
opacity: 0;
|
||||
-webkit-animation: noty_modal_in .3s ease-out;
|
||||
animation: noty_modal_in .3s ease-out; }
|
||||
|
||||
.noty_modal.noty_modal_close {
|
||||
-webkit-animation: noty_modal_out .3s ease-out;
|
||||
animation: noty_modal_out .3s ease-out;
|
||||
-webkit-animation-fill-mode: forwards;
|
||||
animation-fill-mode: forwards; }
|
||||
|
||||
@-webkit-keyframes noty_modal_in {
|
||||
100% {
|
||||
opacity: .3; } }
|
||||
|
||||
@keyframes noty_modal_in {
|
||||
100% {
|
||||
opacity: .3; } }
|
||||
|
||||
@-webkit-keyframes noty_modal_out {
|
||||
100% {
|
||||
opacity: 0; } }
|
||||
|
||||
@keyframes noty_modal_out {
|
||||
100% {
|
||||
opacity: 0; } }
|
||||
|
||||
@keyframes noty_modal_out {
|
||||
100% {
|
||||
opacity: 0; } }
|
||||
|
||||
@-webkit-keyframes noty_anim_in {
|
||||
100% {
|
||||
-webkit-transform: translate(0);
|
||||
transform: translate(0);
|
||||
opacity: 1; } }
|
||||
|
||||
@keyframes noty_anim_in {
|
||||
100% {
|
||||
-webkit-transform: translate(0);
|
||||
transform: translate(0);
|
||||
opacity: 1; } }
|
||||
|
||||
@-webkit-keyframes noty_anim_out {
|
||||
100% {
|
||||
-webkit-transform: translate(50%);
|
||||
transform: translate(50%);
|
||||
opacity: 0; } }
|
||||
|
||||
@keyframes noty_anim_out {
|
||||
100% {
|
||||
-webkit-transform: translate(50%);
|
||||
transform: translate(50%);
|
||||
opacity: 0; } }
|
||||
|
||||
@-webkit-keyframes noty_anim_height {
|
||||
100% {
|
||||
height: 0; } }
|
||||
|
||||
@keyframes noty_anim_height {
|
||||
100% {
|
||||
height: 0; } }
|
||||
|
||||
/*# sourceMappingURL=noty.css.map*/
|
||||
+17
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";e.addTheme("amazon",{render:e=>{const{type:n,message:t}=e,r="error"===n||"warning"===n;return`\n <div class="fl-amazon fl-${n}" role="${r?"alert":"status"}" aria-live="${r?"assertive":"polite"}" aria-atomic="true">\n <div class="fl-amazon-alert">\n <div class="fl-alert-content">\n <div class="fl-icon-container">\n ${(()=>{switch(n){case"success":return'<svg viewBox="0 0 24 24" width="24" height="24">\n <path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>\n </svg>';case"error":return'<svg viewBox="0 0 24 24" width="24" height="24">\n <path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/>\n </svg>';case"warning":return'<svg viewBox="0 0 24 24" width="24" height="24">\n <path fill="currentColor" d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"/>\n </svg>';case"info":return'<svg viewBox="0 0 24 24" width="24" height="24">\n <path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"/>\n </svg>'}return""})()}\n </div>\n <div class="fl-text-content">\n <div class="fl-alert-title">${(()=>{switch(n){case"success":return"Success!";case"error":return"Problem";case"warning":return"Warning";case"info":return"Information";default:return"Alert"}})()}</div>\n <div class="fl-alert-message">${t}</div>\n </div>\n </div>\n <div class="fl-alert-actions">\n <button class="fl-close" aria-label="Close notification">\n <svg viewBox="0 0 24 24" width="16" height="16">\n <path fill="currentColor" d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>\n </svg>\n </button>\n </div>\n </div>\n </div>`}})}));
|
||||
@@ -0,0 +1 @@
|
||||
.fl-amber{--amber-bg-light:#fff;--amber-bg-dark:#1e293b;--amber-text-light:#4b5563;--amber-text-dark:#f1f5f9;--amber-shadow:0 5px 15px rgba(0,0,0,.08);--amber-shadow-dark:0 5px 15px rgba(0,0,0,.2);--amber-border-radius:4px;--amber-success:#10b981;--amber-info:#3b82f6;--amber-warning:#f59e0b;--amber-error:#ef4444}@keyframes amberIn{0%{opacity:0;transform:translateY(-12px)}to{opacity:1;transform:translateY(0)}}.fl-amber{animation:amberIn .3s ease-out;background-color:var(--amber-bg-light);border-radius:var(--amber-border-radius) var(--amber-border-radius) 0 0;box-shadow:var(--amber-shadow);color:var(--amber-text-light);font-family:var(--fl-font),serif;margin:.6rem 0;padding:.85rem 1rem;position:relative;will-change:transform,opacity}.fl-amber .fl-content{align-items:center;display:flex}.fl-amber .fl-icon{font-size:1.85em;margin-right:.8rem}.fl-amber .fl-text{flex:1}.fl-amber .fl-message{font-size:.875em;line-height:1.4}.fl-amber .fl-close{background:none;border:none;color:currentColor;cursor:pointer;flex-shrink:0;font-size:1.15rem;margin-left:1rem;opacity:.6;padding:.25rem;touch-action:manipulation;transition:opacity .2s}.fl-amber .fl-close:focus,.fl-amber .fl-close:hover{opacity:1}.fl-amber .fl-progress-bar{bottom:0;height:3px;left:0;overflow:hidden;position:absolute;right:0}.fl-amber .fl-progress-bar .fl-progress{height:100%;width:100%}.fl-amber.fl-success .fl-close{color:var(--amber-success)}.fl-amber.fl-info .fl-close{color:var(--amber-info)}.fl-amber.fl-warning .fl-close{color:var(--amber-warning)}.fl-amber.fl-error .fl-close{color:var(--amber-error)}.fl-amber.fl-rtl{direction:rtl}.fl-amber.fl-rtl .fl-icon{margin-left:.8rem;margin-right:0}.fl-amber.fl-rtl .fl-close{margin-left:0;margin-right:1rem}.fl-amber.fl-rtl .fl-progress .fl-progress{transform-origin:right center}@media (prefers-reduced-motion:reduce){.fl-amber{animation:none}}.fl-amber.fl-auto-dark,body.fl-dark .fl-amber,html.fl-dark .fl-amber{background-color:var(--amber-bg-dark);box-shadow:var(--amber-shadow-dark);color:var(--amber-text-dark)}
|
||||
@@ -0,0 +1 @@
|
||||
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";e.addTheme("amber",{render:e=>{const{type:s,message:i}=e,l="error"===s||"warning"===s;return`\n <div class="fl-amber fl-${s}" role="${l?"alert":"status"}" aria-live="${l?"assertive":"polite"}" aria-atomic="true">\n <div class="fl-content">\n <div class="fl-icon"></div>\n <div class="fl-text">\n <div class="fl-message">${i}</div>\n </div>\n <button class="fl-close" aria-label="Close ${s} message">×</button>\n </div>\n <div class="fl-progress-bar">\n <div class="fl-progress"></div>\n </div>\n </div>`}})}));
|
||||
@@ -0,0 +1 @@
|
||||
.fl-aurora{--aurora-bg-light:#fff;--aurora-bg-dark:#14141c;--aurora-text-light:#1e293b;--aurora-text-dark:#f8fafc;--aurora-shadow:0 8px 25px rgba(0,0,0,.08);--aurora-shadow-dark:0 10px 30px rgba(0,0,0,.16);--aurora-border-radius:4px;--aurora-blur:15px;--aurora-success-gradient:linear-gradient(135deg,rgba(16,185,129,.08),rgba(16,185,129,.2));--aurora-info-gradient:linear-gradient(135deg,rgba(59,130,246,.08),rgba(59,130,246,.2));--aurora-warning-gradient:linear-gradient(135deg,rgba(245,158,11,.08),rgba(245,158,11,.2));--aurora-error-gradient:linear-gradient(135deg,rgba(239,68,68,.08),rgba(239,68,68,.2));--aurora-success:#10b981;--aurora-info:#3b82f6;--aurora-warning:#f59e0b;--aurora-error:#ef4444}@keyframes auroraFadeIn{0%{opacity:0;transform:translateY(-12px) scale(.98)}to{opacity:1;transform:translateY(0) scale(1)}}.fl-aurora{animation:auroraFadeIn .35s cubic-bezier(.21,1.02,.73,1);backdrop-filter:blur(var(--aurora-blur));-webkit-backdrop-filter:blur(var(--aurora-blur));background-color:var(--aurora-bg-light);border-radius:var(--aurora-border-radius) var(--aurora-border-radius) 0 0;box-shadow:var(--aurora-shadow);color:var(--aurora-text-light);font-family:var(--fl-font),sans-serif;margin:10px 0;overflow:hidden;padding:16px 18px;position:relative;will-change:transform,opacity}.fl-aurora:before{border-radius:inherit;content:"";inset:0;opacity:.8;position:absolute;z-index:0}.fl-aurora .fl-content{align-items:center;display:flex;position:relative;z-index:1}.fl-aurora .fl-message{flex:1;font-size:.9375rem;font-weight:500;line-height:1.5;margin-right:10px}.fl-aurora .fl-close{align-items:center;background:rgba(0,0,0,.05);border:none;border-radius:50%;color:inherit;cursor:pointer;display:flex;flex-shrink:0;font-size:1rem;height:28px;justify-content:center;opacity:.7;transition:all .2s ease;width:28px}.fl-aurora .fl-close:focus,.fl-aurora .fl-close:hover{background:rgba(0,0,0,.1);opacity:1}.fl-aurora .fl-progress-bar{border-radius:6px;bottom:2px;height:3px;left:2px;opacity:.7;overflow:hidden;position:absolute;right:2px;z-index:1}.fl-aurora .fl-progress{height:100%;width:100%}.fl-aurora.fl-success:before{background:var(--aurora-success-gradient)}.fl-aurora.fl-success .fl-progress{background-color:var(--aurora-success)}.fl-aurora.fl-info:before{background:var(--aurora-info-gradient)}.fl-aurora.fl-info .fl-progress{background-color:var(--aurora-info)}.fl-aurora.fl-warning:before{background:var(--aurora-warning-gradient)}.fl-aurora.fl-warning .fl-progress{background-color:var(--aurora-warning)}.fl-aurora.fl-error:before{background:var(--aurora-error-gradient)}.fl-aurora.fl-error .fl-progress{background-color:var(--aurora-error)}.fl-aurora.fl-rtl{direction:rtl}.fl-aurora.fl-rtl .fl-message{margin-left:10px;margin-right:0}.fl-aurora.fl-rtl .fl-progress{transform-origin:right center}@media (prefers-reduced-motion:reduce){.fl-aurora{animation:none}}.fl-aurora.fl-auto-dark,body.fl-dark .fl-aurora,html.fl-dark .fl-aurora{background-color:var(--aurora-bg-dark);box-shadow:var(--aurora-shadow-dark);color:var(--aurora-text-dark)}.fl-aurora.fl-auto-dark .fl-close,body.fl-dark .fl-aurora .fl-close,html.fl-dark .fl-aurora .fl-close{background:hsla(0,0%,100%,.1)}.fl-aurora.fl-auto-dark .fl-close:focus,.fl-aurora.fl-auto-dark .fl-close:hover,body.fl-dark .fl-aurora .fl-close:focus,body.fl-dark .fl-aurora .fl-close:hover,html.fl-dark .fl-aurora .fl-close:focus,html.fl-dark .fl-aurora .fl-close:hover{background:hsla(0,0%,100%,.15)}.fl-aurora.fl-auto-dark.fl-success:before,body.fl-dark .fl-aurora.fl-success:before,html.fl-dark .fl-aurora.fl-success:before{background:linear-gradient(135deg,rgba(16,185,129,.1),rgba(16,185,129,.25))}.fl-aurora.fl-auto-dark.fl-info:before,body.fl-dark .fl-aurora.fl-info:before,html.fl-dark .fl-aurora.fl-info:before{background:linear-gradient(135deg,rgba(59,130,246,.1),rgba(59,130,246,.25))}.fl-aurora.fl-auto-dark.fl-warning:before,body.fl-dark .fl-aurora.fl-warning:before,html.fl-dark .fl-aurora.fl-warning:before{background:linear-gradient(135deg,rgba(245,158,11,.1),rgba(245,158,11,.25))}.fl-aurora.fl-auto-dark.fl-error:before,body.fl-dark .fl-aurora.fl-error:before,html.fl-dark .fl-aurora.fl-error:before{background:linear-gradient(135deg,rgba(239,68,68,.1),rgba(239,68,68,.25))}
|
||||
@@ -0,0 +1 @@
|
||||
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";e.addTheme("aurora",{render:e=>{const{type:s,message:a}=e,r="error"===s||"warning"===s;return`\n <div class="fl-aurora fl-${s}" role="${r?"alert":"status"}" aria-live="${r?"assertive":"polite"}" aria-atomic="true">\n <div class="fl-content">\n <div class="fl-message">${a}</div>\n <button class="fl-close" aria-label="Close ${s} message">×</button>\n </div>\n <div class="fl-progress-bar">\n <div class="fl-progress"></div>\n </div>\n </div>`}})}));
|
||||
@@ -0,0 +1 @@
|
||||
.fl-crystal{--crystal-bg-light:#fff;--crystal-bg-dark:rgba(30,30,30,.95);--crystal-text-light:#2c3e50;--crystal-text-dark:hsla(0,0%,100%,.95);--crystal-shadow:rgba(0,0,0,.08);--crystal-shadow-dark:rgba(0,0,0,.25)}@keyframes crystalIn{0%{opacity:0;transform:translateY(-20px)}to{opacity:1;transform:translateY(0)}}@keyframes crystalPulse{0%{box-shadow:0 2px 8px var(--crystal-shadow)}50%{box-shadow:0 4px 12px var(--crystal-shadow)}to{box-shadow:0 2px 8px var(--crystal-shadow)}}.fl-crystal{animation:crystalIn .3s ease-out;background:var(--crystal-bg-light,var(--fl-bg-light));border-radius:var(--fl-border-radius,4px) var(--fl-border-radius,4px) 0 0;box-shadow:0 2px 8px var(--crystal-shadow);font-family:var(--fl-font),serif;margin:0 0 1rem;position:relative;transition:box-shadow .3s ease;will-change:transform,opacity}.fl-crystal:hover{animation:crystalPulse 2s ease-in-out infinite}.fl-crystal .fl-content{align-items:center;display:flex;gap:.75rem;padding:1rem 2.5rem 1rem 1rem}.fl-crystal .fl-text{flex:1}.fl-crystal .fl-message{color:var(--crystal-text-light,var(--fl-text-light));font-size:.9375rem;line-height:1.4;margin:0}.fl-crystal .fl-close{background:none;border:none;color:currentColor;cursor:pointer;font-size:1.25rem;line-height:1;opacity:.5;padding:.25rem;position:absolute;right:.75rem;top:50%;touch-action:manipulation;transform:translateY(-50%);transition:all .2s ease}.fl-crystal .fl-close:focus,.fl-crystal .fl-close:hover{opacity:1;transform:translateY(-50%) scale(1.1)}.fl-crystal .fl-progress-bar{bottom:0;height:3px;left:0;overflow:hidden;position:absolute;right:0}.fl-crystal .fl-progress-bar .fl-progress{height:100%;transform-origin:left center;width:100%}.fl-crystal.fl-success,.fl-crystal.fl-success .fl-message{color:var(--success-color,var(--fl-success))}.fl-crystal.fl-error,.fl-crystal.fl-error .fl-message{color:var(--error-color,var(--fl-error))}.fl-crystal.fl-warning,.fl-crystal.fl-warning .fl-message{color:var(--warning-color,var(--fl-warning))}.fl-crystal.fl-info,.fl-crystal.fl-info .fl-message{color:var(--info-color,var(--fl-info))}.fl-crystal.fl-rtl{direction:rtl}.fl-crystal.fl-rtl .fl-content{padding:1rem 1rem 1rem 2.5rem}.fl-crystal.fl-rtl .fl-close{left:.75rem;right:auto}.fl-crystal.fl-rtl .fl-progress .fl-progress{transform-origin:right center}@media (prefers-reduced-motion:reduce){.fl-crystal{animation:none}.fl-crystal:hover{animation:none;box-shadow:0 2px 8px var(--crystal-shadow)}}.fl-crystal.fl-auto-dark,body.fl-dark .fl-crystal,html.fl-dark .fl-crystal{background-color:var(--crystal-bg-dark,var(--fl-bg-dark));box-shadow:0 2px 8px var(--crystal-shadow-dark)}.fl-crystal.fl-auto-dark .fl-message,body.fl-dark .fl-crystal .fl-message,html.fl-dark .fl-crystal .fl-message{color:var(--crystal-text-dark,var(--fl-text-dark))}.fl-crystal.fl-auto-dark:hover,body.fl-dark .fl-crystal:hover,html.fl-dark .fl-crystal:hover{animation:none;box-shadow:0 4px 16px var(--crystal-shadow-dark)}
|
||||
@@ -0,0 +1 @@
|
||||
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";e.addTheme("crystal",{render:e=>{const{type:s,message:l}=e,a="error"===s||"warning"===s;return`\n <div class="fl-crystal fl-${s}" role="${a?"alert":"status"}" aria-live="${a?"assertive":"polite"}" aria-atomic="true">\n <div class="fl-content">\n <div class="fl-text">\n <p class="fl-message">${l}</p>\n </div>\n <button class="fl-close" aria-label="Close ${s} message">×</button>\n </div>\n <div class="fl-progress-bar">\n <div class="fl-progress"></div>\n </div>\n </div>`}})}));
|
||||
@@ -0,0 +1 @@
|
||||
.fl-emerald{--emerald-bg-light:#fff;--emerald-bg-dark:#1e1e1e;--emerald-text-light:#333;--emerald-text-dark:hsla(0,0%,100%,.9);--emerald-shadow:rgba(0,0,0,.1);--emerald-blur:8px;--emerald-success:var(--success-color,#16a085);--emerald-error:var(--error-color,#e74c3c);--emerald-warning:var(--warning-color,#f39c12);--emerald-info:var(--info-color,#3498db)}@keyframes emeraldIn{0%{opacity:0;transform:scale(.5) translateY(20px)}60%{opacity:1;transform:scale(1.1) translateY(-5px)}to{opacity:1;transform:scale(1) translateY(0)}}.fl-emerald{animation:emeraldIn .5s cubic-bezier(.23,1,.32,1);backdrop-filter:blur(var(--emerald-blur));-webkit-backdrop-filter:blur(var(--emerald-blur));background:var(--emerald-bg-light);border-radius:4px 4px 0 0;box-shadow:0 10px 20px var(--emerald-shadow);color:var(--emerald-text-light);font-family:"Inter",var(--fl-font),serif;margin:0 0 .5rem;overflow:hidden;padding:1rem 1.5rem 1rem 1rem;position:relative}.fl-emerald .fl-content{align-items:center;display:flex}.fl-emerald .fl-message{flex:1;font-size:.9rem;font-weight:500;line-height:1.4}.fl-emerald .fl-close{background:transparent;border:none;color:currentColor;cursor:pointer;font-size:1.3rem;margin-left:auto;opacity:.7;transition:opacity .2s ease}.fl-emerald .fl-close:focus,.fl-emerald .fl-close:hover{opacity:1}.fl-emerald.fl-success{color:var(--emerald-success)}.fl-emerald.fl-error{color:var(--emerald-error)}.fl-emerald.fl-warning{color:var(--emerald-warning)}.fl-emerald.fl-info{color:var(--emerald-info)}.fl-emerald.fl-rtl{direction:rtl;padding:1rem 1rem 1rem 1.5rem}.fl-emerald.fl-rtl .fl-content{flex-direction:row-reverse}.fl-emerald.fl-rtl .fl-close{margin-left:0;margin-right:auto}@media (prefers-reduced-motion:reduce){.fl-emerald{animation:none}}.fl-emerald.fl-auto-dark,body.fl-dark .fl-emerald,html.fl-dark .fl-emerald{background:var(--emerald-bg-dark)}.fl-emerald.fl-auto-dark .fl-message,body.fl-dark .fl-emerald .fl-message,html.fl-dark .fl-emerald .fl-message{color:var(--emerald-text-dark)}
|
||||
@@ -0,0 +1 @@
|
||||
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";e.addTheme("emerald",{render:e=>{const{type:s,message:a}=e,l="error"===s||"warning"===s;return`\n <div class="fl-emerald fl-${s}" role="${l?"alert":"status"}" aria-live="${l?"assertive":"polite"}" aria-atomic="true">\n <div class="fl-content">\n <div class="fl-message">${a}</div>\n <button class="fl-close" aria-label="Close ${s} message">×</button>\n </div>\n </div>`}})}));
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
!function(n,i){"object"==typeof exports&&"undefined"!=typeof module?i(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],i):i((n="undefined"!=typeof globalThis?globalThis:n||self).flasher)}(this,(function(n){"use strict";const i={render:n=>{const{type:i,message:e}=n,s="error"===i||"warning"===i,t=s?"alert":"status",l=s?"assertive":"polite",o=(new Date).toLocaleTimeString([],{hour:"numeric",minute:"2-digit"});return`\n <div class="fl-facebook fl-${i}" role="${t}" aria-live="${l}" aria-atomic="true">\n <div class="fl-fb-notification">\n <div class="fl-icon-container">\n ${(()=>{switch(i){case"success":return'<div class="fl-fb-icon fl-fb-icon-success">\n <svg viewBox="0 0 24 24" width="16" height="16">\n <path fill="currentColor" d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm-1-11v6h2v-6h-2zm0-4v2h2V7h-2z"/>\n </svg>\n </div>';case"error":return'<div class="fl-fb-icon fl-fb-icon-error">\n <svg viewBox="0 0 24 24" width="16" height="16">\n <path fill="currentColor" d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-11.5c-.69 0-1.25.56-1.25 1.25S11.31 13 12 13s1.25-.56 1.25-1.25S12.69 10.5 12 10.5zM12 9c.552 0 1-.448 1-1V7c0-.552-.448-1-1-1s-1 .448-1 1v1c0 .552.448 1 1 1z"/>\n </svg>\n </div>';case"warning":return'<div class="fl-fb-icon fl-fb-icon-warning">\n <svg viewBox="0 0 24 24" width="16" height="16">\n <path fill="currentColor" d="M12.865 3.00017L22.3912 19.5002C22.6674 19.9785 22.5035 20.5901 22.0252 20.8662C21.8732 20.954 21.7008 21.0002 21.5252 21.0002H2.47266C1.92037 21.0002 1.47266 20.5525 1.47266 20.0002C1.47266 19.8246 1.51886 19.6522 1.60663 19.5002L11.1329 3.00017C11.409 2.52187 12.0206 2.358 12.4989 2.63414C12.651 2.72192 12.7772 2.84815 12.865 3.00017ZM11 16.0002V18.0002H13V16.0002H11ZM11 8.00017V14.0002H13V8.00017H11Z"/>\n </svg>\n </div>';case"info":return'<div class="fl-fb-icon fl-fb-icon-info">\n <svg viewBox="0 0 24 24" width="16" height="16">\n <path fill="currentColor" d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-2a8 8 0 100-16 8 8 0 000 16zm-1-5h2v-2h-2v2zm0-4h2V7h-2v4z"/>\n </svg>\n </div>'}return""})()}\n </div>\n <div class="fl-content">\n <div class="fl-message">\n ${e}\n </div>\n <div class="fl-meta">\n <span class="fl-time">${o}</span>\n </div>\n </div>\n <div class="fl-actions">\n <button class="fl-button fl-close" aria-label="Close ${i} message">\n <div class="fl-button-icon">\n <svg viewBox="0 0 24 24" width="20" height="20">\n <path fill="currentColor" d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12 19 6.41z"/>\n </svg>\n </div>\n </button>\n </div>\n </div>\n </div>`}};n.addTheme("facebook",i)}));
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";e.addTheme("flasher",{render:e=>{const{type:s,title:n,message:a}=e,l="error"===s||"warning"===s,t=l?"alert":"status",r=l?"assertive":"polite",i=n||s.charAt(0).toUpperCase()+s.slice(1);return`\n <div class="fl-flasher fl-${s}" role="${t}" aria-live="${r}" aria-atomic="true">\n <div class="fl-content">\n <div class="fl-icon"></div>\n <div>\n <strong class="fl-title">${i}</strong>\n <span class="fl-message">${a}</span>\n </div>\n <button class="fl-close" aria-label="Close ${s} message">×</button>\n </div>\n <span class="fl-progress-bar">\n <span class="fl-progress"></span>\n </span>\n </div>`}})}));
|
||||
@@ -0,0 +1 @@
|
||||
.fl-google{--md-bg-light:#fff;--md-bg-dark:#2d2d2d;--md-text-light:rgba(0,0,0,.87);--md-text-secondary-light:rgba(0,0,0,.6);--md-text-dark:hsla(0,0%,100%,.87);--md-text-secondary-dark:hsla(0,0%,100%,.6);--md-elevation:0 3px 5px -1px rgba(0,0,0,.2),0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12);--md-elevation-dark:0 3px 5px -1px rgba(0,0,0,.4),0 6px 10px 0 rgba(0,0,0,.28),0 1px 18px 0 rgba(0,0,0,.24);--md-border-radius:4px;--md-success:#43a047;--md-info:#1e88e5;--md-warning:#fb8c00;--md-error:#e53935;--md-animation-duration:0.3s;--md-ripple-duration:0.6s}@keyframes mdSlideUp{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}@keyframes mdRipple{to{opacity:0;transform:scale(4)}}.fl-google{animation:mdSlideUp var(--md-animation-duration) cubic-bezier(.4,0,.2,1);font-family:Roboto,Segoe UI,Helvetica,Arial,sans-serif;margin:8px 0;position:relative}.fl-google .fl-md-card{background-color:var(--md-bg-light);border-radius:var(--md-border-radius);box-shadow:var(--md-elevation);color:var(--md-text-light);overflow:hidden}.fl-google .fl-content{align-items:flex-start;display:flex;padding:16px}.fl-google .fl-icon-wrapper{color:var(--md-text-secondary-light);flex-shrink:0;margin-right:16px}.fl-google .fl-text-content{flex:1}.fl-google .fl-title{font-size:1rem;font-weight:500;margin-bottom:4px}.fl-google .fl-message{color:var(--md-text-secondary-light);font-size:.875rem;line-height:1.43}.fl-google .fl-actions{display:flex;justify-content:flex-end;padding:8px}.fl-google .fl-action-button{background:transparent;border:none;border-radius:4px;color:currentColor;cursor:pointer;font-family:inherit;font-size:.8125rem;font-weight:500;letter-spacing:.0892857143em;overflow:hidden;padding:8px 12px;position:relative;text-transform:uppercase;transition:background-color .2s}.fl-google .fl-action-button:focus,.fl-google .fl-action-button:hover{background-color:rgba(0,0,0,.04)}.fl-google .fl-action-button:after{background:currentColor;border-radius:50%;content:"";height:5px;opacity:0;pointer-events:none;position:absolute;transform:scale(1);width:5px}.fl-google .fl-action-button:active:after{animation:mdRipple var(--md-ripple-duration) linear;opacity:.3}.fl-google.fl-success .fl-action-button,.fl-google.fl-success .fl-icon-wrapper{color:var(--md-success)}.fl-google.fl-info .fl-action-button,.fl-google.fl-info .fl-icon-wrapper{color:var(--md-info)}.fl-google.fl-warning .fl-action-button,.fl-google.fl-warning .fl-icon-wrapper{color:var(--md-warning)}.fl-google.fl-error .fl-action-button,.fl-google.fl-error .fl-icon-wrapper{color:var(--md-error)}.fl-google .fl-progress-bar{bottom:0;height:4px;left:0;overflow:hidden;position:absolute;right:0}.fl-google .fl-progress-bar .fl-progress{height:100%;transform-origin:left center;width:100%}.fl-google.fl-success .fl-progress{background-color:var(--md-success)}.fl-google.fl-info .fl-progress{background-color:var(--md-info)}.fl-google.fl-warning .fl-progress{background-color:var(--md-warning)}.fl-google.fl-error .fl-progress{background-color:var(--md-error)}.fl-google.fl-rtl{direction:rtl}.fl-google.fl-rtl .fl-content{flex-direction:row-reverse}.fl-google.fl-rtl .fl-icon-wrapper{margin-left:16px;margin-right:0}.fl-google.fl-rtl .fl-actions{justify-content:flex-start}.fl-google.fl-rtl .fl-progress{transform-origin:right center}@media (prefers-reduced-motion:reduce){.fl-google,.fl-google .fl-action-button:active:after{animation:none}}.fl-google.fl-auto-dark .fl-md-card,body.fl-dark .fl-google .fl-md-card,html.fl-dark .fl-google .fl-md-card{background-color:var(--md-bg-dark);box-shadow:var(--md-elevation-dark);color:var(--md-text-dark)}.fl-google.fl-auto-dark .fl-message,body.fl-dark .fl-google .fl-message,html.fl-dark .fl-google .fl-message{color:var(--md-text-secondary-dark)}.fl-google.fl-auto-dark .fl-action-button:focus,.fl-google.fl-auto-dark .fl-action-button:hover,body.fl-dark .fl-google .fl-action-button:focus,body.fl-dark .fl-google .fl-action-button:hover,html.fl-dark .fl-google .fl-action-button:focus,html.fl-dark .fl-google .fl-action-button:hover{background-color:hsla(0,0%,100%,.08)}
|
||||
@@ -0,0 +1 @@
|
||||
!function(s,e){"object"==typeof exports&&"undefined"!=typeof module?e(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],e):e((s="undefined"!=typeof globalThis?globalThis:s||self).flasher)}(this,(function(s){"use strict";s.addTheme("google",{render:s=>{const{type:e,message:n,title:l}=s,i="error"===e||"warning"===e,t=l?`<div class="fl-title">${l}</div>`:"";return`\n <div class="fl-google fl-${e}" role="${i?"alert":"status"}" aria-live="${i?"assertive":"polite"}" aria-atomic="true">\n <div class="fl-md-card">\n <div class="fl-content">\n <div class="fl-icon-wrapper">\n ${(()=>{switch(e){case"success":return'<svg class="fl-icon-svg" viewBox="0 0 24 24" width="24" height="24">\n <path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>\n </svg>';case"error":return'<svg class="fl-icon-svg" viewBox="0 0 24 24" width="24" height="24">\n <path fill="currentColor" d="M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z"/>\n </svg>';case"warning":return'<svg class="fl-icon-svg" viewBox="0 0 24 24" width="24" height="24">\n <path fill="currentColor" d="M12 5.99L19.53 19H4.47L12 5.99M12 2L1 21h22L12 2zm1 14h-2v2h2v-2zm0-6h-2v4h2v-4z"/>\n </svg>';case"info":return'<svg class="fl-icon-svg" viewBox="0 0 24 24" width="24" height="24">\n <path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"/>\n </svg>'}return""})()}\n </div>\n <div class="fl-text-content">\n ${t}\n <div class="fl-message">${n}</div>\n </div>\n </div>\n <div class="fl-actions">\n <button class="fl-action-button fl-close" aria-label="Close ${e} message">\n DISMISS\n </button>\n </div>\n </div>\n <div class="fl-progress-bar">\n <div class="fl-progress"></div>\n </div>\n </div>`}})}));
|
||||
@@ -0,0 +1 @@
|
||||
.fl-ios{--ios-bg-light:#fff;--ios-bg-dark:#1e1e1e;--ios-text-light:#000;--ios-text-secondary-light:#6e6e6e;--ios-text-dark:#fff;--ios-text-secondary-dark:#a8a8a8;--ios-border-radius:13px;--ios-shadow:0 2px 12px rgba(0,0,0,.15);--ios-shadow-dark:0 2px 12px rgba(0,0,0,.35);--ios-icon-size:18px;--ios-blur:30px;--ios-success:#34c759;--ios-info:#007aff;--ios-warning:#ff9500;--ios-error:#ff3b30;--ios-animation-duration:0.4s}@keyframes iosSlideIn{0%{opacity:0;transform:translateY(-15px) scale(.96)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes iosExpand{0%{max-height:0;opacity:0}to{max-height:100px;opacity:1}}.fl-ios{animation:iosSlideIn var(--ios-animation-duration) cubic-bezier(.23,1,.32,1);font-family:-apple-system,BlinkMacSystemFont,San Francisco,Helvetica Neue,Helvetica,Arial,sans-serif;margin:10px 0;position:relative;will-change:transform,opacity}.fl-ios .fl-ios-notification{backdrop-filter:blur(var(--ios-blur));-webkit-backdrop-filter:blur(var(--ios-blur));background-color:var(--ios-bg-light);border-radius:var(--ios-border-radius);box-shadow:var(--ios-shadow);color:var(--ios-text-light);padding:12px 15px;position:relative}.fl-ios .fl-header{align-items:center;display:flex;margin-bottom:8px;padding-right:20px}.fl-ios .fl-app-icon{align-items:center;background-color:currentColor;border-radius:5px;display:flex;flex-shrink:0;height:22px;justify-content:center;margin-right:8px;width:22px}.fl-ios .fl-icon-svg{color:#fff;height:14px;width:14px}.fl-ios .fl-app-info{align-items:baseline;display:flex;flex:1;justify-content:space-between}.fl-ios .fl-app-name{font-size:.85rem;font-weight:600}.fl-ios .fl-time{color:var(--ios-text-secondary-light);flex-shrink:0;font-size:.75rem;margin-left:5px}.fl-ios .fl-content{animation:iosExpand .3s forwards;animation-delay:.1s;overflow:hidden}.fl-ios .fl-message{font-size:.95rem;line-height:1.3;margin:0;padding-right:15px}.fl-ios .fl-close{align-items:center;background-color:rgba(0,0,0,.1);border:none;border-radius:50%;color:var(--ios-text-light);cursor:pointer;display:flex;font-size:14px;height:18px;justify-content:center;line-height:1;opacity:.7;padding:0;position:absolute;right:12px;top:10px;transition:opacity .2s;width:18px}.fl-ios .fl-close:focus,.fl-ios .fl-close:hover{opacity:1}.fl-ios.fl-success .fl-app-icon{color:var(--ios-success)}.fl-ios.fl-info .fl-app-icon{color:var(--ios-info)}.fl-ios.fl-warning .fl-app-icon{color:var(--ios-warning)}.fl-ios.fl-error .fl-app-icon{color:var(--ios-error)}.fl-ios.fl-rtl{direction:rtl}.fl-ios.fl-rtl .fl-header{padding-left:20px;padding-right:0}.fl-ios.fl-rtl .fl-app-icon{margin-left:8px;margin-right:0}.fl-ios.fl-rtl .fl-time{margin-left:0;margin-right:5px}.fl-ios.fl-rtl .fl-message{padding-left:15px;padding-right:0}.fl-ios.fl-rtl .fl-close{left:12px;right:auto}@media (prefers-reduced-motion:reduce){.fl-ios{animation:none}.fl-ios .fl-content{animation:none;max-height:none;opacity:1}}@media screen and (max-width:480px){.fl-ios{width:100%}}.fl-ios.fl-auto-dark .fl-ios-notification,body.fl-dark .fl-ios .fl-ios-notification,html.fl-dark .fl-ios .fl-ios-notification{background-color:var(--ios-bg-dark);box-shadow:var(--ios-shadow-dark);color:var(--ios-text-dark)}.fl-ios.fl-auto-dark .fl-time,body.fl-dark .fl-ios .fl-time,html.fl-dark .fl-ios .fl-time{color:var(--ios-text-secondary-dark)}.fl-ios.fl-auto-dark .fl-close,body.fl-dark .fl-ios .fl-close,html.fl-dark .fl-ios .fl-close{background-color:hsla(0,0%,100%,.2);color:var(--ios-text-dark)}
|
||||
@@ -0,0 +1 @@
|
||||
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";const s={render:e=>{const{type:s,message:i,title:n}=e,l="error"===s||"warning"===s,t=l?"alert":"status",a=l?"assertive":"polite",r=(new Date).toLocaleTimeString([],{hour:"numeric",minute:"2-digit"}),o=n||"PHPFlasher";return`\n <div class="fl-ios fl-${s}" role="${t}" aria-live="${a}" aria-atomic="true">\n <div class="fl-ios-notification">\n <div class="fl-header">\n <div class="fl-app-icon">\n ${(()=>{switch(s){case"success":return'<svg class="fl-icon-svg" viewBox="0 0 24 24" width="20" height="20">\n <path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/>\n </svg>';case"error":return'<svg class="fl-icon-svg" viewBox="0 0 24 24" width="20" height="20">\n <path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/>\n </svg>';case"warning":return'<svg class="fl-icon-svg" viewBox="0 0 24 24" width="20" height="20">\n <path fill="currentColor" d="M1 21h22L12 2 1 21zm12-3h-2v-2h2v2zm0-4h-2v-4h2v4z"/>\n </svg>';case"info":return'<svg class="fl-icon-svg" viewBox="0 0 24 24" width="20" height="20">\n <path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"/>\n </svg>'}return""})()}\n </div>\n <div class="fl-app-info">\n <div class="fl-app-name">${o}</div>\n <div class="fl-time">${r}</div>\n </div>\n </div>\n <div class="fl-content">\n <div class="fl-message">${i}</div>\n </div>\n <button class="fl-close" aria-label="Close ${s} message">\n <span aria-hidden="true">×</span>\n </button>\n </div>\n </div>`}};e.addTheme("ios",s)}));
|
||||
@@ -0,0 +1 @@
|
||||
.fl-jade{--jade-text-light:#5f6c7b;--jade-text-dark:#e2e8f0;--jade-shadow:0 8px 24px hsla(210,8%,62%,.1);--jade-shadow-dark:0 8px 24px rgba(0,0,0,.2);--jade-border-radius:4px;--jade-transition:0.3s cubic-bezier(0.4,0,0.2,1);--jade-success-bg:#f0fdf4;--jade-success-color:#16a34a;--jade-info-bg:#eff6ff;--jade-info-color:#3b82f6;--jade-warning-bg:#fffbeb;--jade-warning-color:#f59e0b;--jade-error-bg:#fef2f2;--jade-error-color:#dc2626;--jade-success-bg-dark:rgba(22,163,74,.15);--jade-info-bg-dark:rgba(59,130,246,.15);--jade-warning-bg-dark:rgba(245,158,11,.15);--jade-error-bg-dark:rgba(220,38,38,.15)}@keyframes jadeIn{0%{opacity:0;transform:translateY(-10px) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}.fl-jade{animation:jadeIn .4s var(--jade-transition);border:1px solid transparent;border-radius:var(--jade-border-radius) var(--jade-border-radius) 0 0;box-shadow:var(--jade-shadow);font-family:var(--fl-font),serif;margin:.5rem 0;overflow:hidden;padding:1rem 1.25rem;position:relative;will-change:transform,opacity}.fl-jade .fl-content{align-items:center;display:flex}.fl-jade .fl-message{flex:1;font-size:.875rem;font-weight:500;line-height:1.5;padding-right:.75rem}.fl-jade .fl-close{align-items:center;background:none;border:none;border-radius:50%;cursor:pointer;display:flex;flex-shrink:0;font-size:1.125rem;height:1.875rem;justify-content:center;opacity:.6;padding:.375rem;transition:all var(--jade-transition);width:1.875rem}.fl-jade .fl-close:focus,.fl-jade .fl-close:hover{background-color:rgba(0,0,0,.05);opacity:1}.fl-jade .fl-progress-bar{border-radius:0 0 var(--jade-border-radius) var(--jade-border-radius);bottom:0;height:3px;left:0;opacity:.7;overflow:hidden;position:absolute;right:0}.fl-jade .fl-progress-bar .fl-progress{height:100%;width:100%}.fl-jade.fl-success{background-color:var(--jade-success-bg);border-color:rgba(22,163,74,.1)}.fl-jade.fl-success,.fl-jade.fl-success .fl-close{color:var(--jade-success-color)}.fl-jade.fl-success .fl-close:focus,.fl-jade.fl-success .fl-close:hover{background-color:rgba(22,163,74,.1)}.fl-jade.fl-success .fl-progress-bar .fl-progress{background-color:var(--jade-success-color)}.fl-jade.fl-info{background-color:var(--jade-info-bg);border-color:rgba(59,130,246,.1)}.fl-jade.fl-info,.fl-jade.fl-info .fl-close{color:var(--jade-info-color)}.fl-jade.fl-info .fl-close:focus,.fl-jade.fl-info .fl-close:hover{background-color:rgba(59,130,246,.1)}.fl-jade.fl-info .fl-progress-bar .fl-progress{background-color:var(--jade-info-color)}.fl-jade.fl-warning{background-color:var(--jade-warning-bg);border-color:rgba(245,158,11,.1)}.fl-jade.fl-warning,.fl-jade.fl-warning .fl-close{color:var(--jade-warning-color)}.fl-jade.fl-warning .fl-close:focus,.fl-jade.fl-warning .fl-close:hover{background-color:rgba(245,158,11,.1)}.fl-jade.fl-warning .fl-progress-bar .fl-progress{background-color:var(--jade-warning-color)}.fl-jade.fl-error{background-color:var(--jade-error-bg);border-color:rgba(220,38,38,.1)}.fl-jade.fl-error,.fl-jade.fl-error .fl-close{color:var(--jade-error-color)}.fl-jade.fl-error .fl-close:focus,.fl-jade.fl-error .fl-close:hover{background-color:rgba(220,38,38,.1)}.fl-jade.fl-error .fl-progress-bar .fl-progress{background-color:var(--jade-error-color)}.fl-jade.fl-rtl{direction:rtl}.fl-jade.fl-rtl .fl-message{padding-left:.75rem;padding-right:0}.fl-jade.fl-rtl .fl-progress .fl-progress{transform-origin:right center}@media (prefers-reduced-motion:reduce){.fl-jade{animation:none}}.fl-jade.fl-auto-dark,body.fl-dark .fl-jade,html.fl-dark .fl-jade{box-shadow:var(--jade-shadow-dark);color:var(--jade-text-dark)}.fl-jade.fl-auto-dark.fl-success,body.fl-dark .fl-jade.fl-success,html.fl-dark .fl-jade.fl-success{background-color:var(--jade-success-bg-dark);border-color:rgba(22,163,74,.2)}.fl-jade.fl-auto-dark.fl-info,body.fl-dark .fl-jade.fl-info,html.fl-dark .fl-jade.fl-info{background-color:var(--jade-info-bg-dark);border-color:rgba(59,130,246,.2)}.fl-jade.fl-auto-dark.fl-warning,body.fl-dark .fl-jade.fl-warning,html.fl-dark .fl-jade.fl-warning{background-color:var(--jade-warning-bg-dark);border-color:rgba(245,158,11,.2)}.fl-jade.fl-auto-dark.fl-error,body.fl-dark .fl-jade.fl-error,html.fl-dark .fl-jade.fl-error{background-color:var(--jade-error-bg-dark);border-color:rgba(220,38,38,.2)}.fl-jade.fl-auto-dark .fl-close:focus,.fl-jade.fl-auto-dark .fl-close:hover,body.fl-dark .fl-jade .fl-close:focus,body.fl-dark .fl-jade .fl-close:hover,html.fl-dark .fl-jade .fl-close:focus,html.fl-dark .fl-jade .fl-close:hover{background-color:hsla(0,0%,100%,.1)}
|
||||
@@ -0,0 +1 @@
|
||||
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";e.addTheme("jade",{render:e=>{const{type:s,message:a}=e,l="error"===s||"warning"===s;return`\n <div class="fl-jade fl-${s}" role="${l?"alert":"status"}" aria-live="${l?"assertive":"polite"}" aria-atomic="true">\n <div class="fl-content">\n <div class="fl-message">${a}</div>\n <button class="fl-close" aria-label="Close ${s} message">×</button>\n </div>\n <div class="fl-progress-bar">\n <div class="fl-progress"></div>\n </div>\n </div>`}})}));
|
||||
@@ -0,0 +1 @@
|
||||
.fl-material{--md-bg-light:#fff;--md-bg-dark:#2d2d2d;--md-text-light:rgba(0,0,0,.87);--md-text-secondary-light:rgba(0,0,0,.6);--md-text-dark:hsla(0,0%,100%,.87);--md-text-secondary-dark:hsla(0,0%,100%,.6);--md-elevation:0 3px 5px -1px rgba(0,0,0,.2),0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12);--md-elevation-dark:0 3px 5px -1px rgba(0,0,0,.4),0 6px 10px 0 rgba(0,0,0,.28),0 1px 18px 0 rgba(0,0,0,.24);--md-border-radius:4px;--md-success:#43a047;--md-info:#1e88e5;--md-warning:#fb8c00;--md-error:#e53935;--md-animation-duration:0.3s;--md-ripple-duration:0.6s}@keyframes mdSlideUp{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}@keyframes mdRipple{to{opacity:0;transform:scale(4)}}.fl-material{animation:mdSlideUp var(--md-animation-duration) cubic-bezier(.4,0,.2,1);font-family:Roboto,Segoe UI,Helvetica,Arial,sans-serif;margin:8px 0;position:relative}.fl-material .fl-md-card{background-color:var(--md-bg-light);border-radius:var(--md-border-radius);box-shadow:var(--md-elevation);color:var(--md-text-light);overflow:hidden}.fl-material .fl-content{align-items:flex-start;display:flex;padding:16px}.fl-material .fl-text-content{flex:1}.fl-material .fl-message{color:var(--md-text-secondary-light);font-size:.875rem;line-height:1.43}.fl-material .fl-actions{display:flex;justify-content:flex-end;padding:8px}.fl-material .fl-action-button{background:transparent;border:none;border-radius:4px;color:currentColor;cursor:pointer;font-family:inherit;font-size:.8125rem;font-weight:500;letter-spacing:.0892857143em;overflow:hidden;padding:8px 12px;position:relative;text-transform:uppercase;transition:background-color .2s}.fl-material .fl-action-button:focus,.fl-material .fl-action-button:hover{background-color:rgba(0,0,0,.04)}.fl-material .fl-action-button:after{background:currentColor;border-radius:50%;content:"";height:5px;opacity:0;pointer-events:none;position:absolute;transform:scale(1);width:5px}.fl-material .fl-action-button:active:after{animation:mdRipple var(--md-ripple-duration) linear;opacity:.3}.fl-material.fl-success .fl-action-button,.fl-material.fl-success .fl-icon-wrapper{color:var(--md-success)}.fl-material.fl-info .fl-action-button,.fl-material.fl-info .fl-icon-wrapper{color:var(--md-info)}.fl-material.fl-warning .fl-action-button,.fl-material.fl-warning .fl-icon-wrapper{color:var(--md-warning)}.fl-material.fl-error .fl-action-button,.fl-material.fl-error .fl-icon-wrapper{color:var(--md-error)}.fl-material .fl-progress-bar{bottom:0;height:4px;left:0;overflow:hidden;position:absolute;right:0}.fl-material .fl-progress-bar .fl-progress{height:100%;transform-origin:left center;width:100%}.fl-material.fl-success .fl-progress{background-color:var(--md-success)}.fl-material.fl-info .fl-progress{background-color:var(--md-info)}.fl-material.fl-warning .fl-progress{background-color:var(--md-warning)}.fl-material.fl-error .fl-progress{background-color:var(--md-error)}.fl-material.fl-rtl{direction:rtl}.fl-material.fl-rtl .fl-content{flex-direction:row-reverse}.fl-material.fl-rtl .fl-icon-wrapper{margin-left:16px;margin-right:0}.fl-material.fl-rtl .fl-actions{justify-content:flex-start}.fl-material.fl-rtl .fl-progress{transform-origin:right center}@media (prefers-reduced-motion:reduce){.fl-material,.fl-material .fl-action-button:active:after{animation:none}}.fl-material.fl-auto-dark .fl-md-card,body.fl-dark .fl-material .fl-md-card,html.fl-dark .fl-material .fl-md-card{background-color:var(--md-bg-dark);box-shadow:var(--md-elevation-dark);color:var(--md-text-dark)}.fl-material.fl-auto-dark .fl-message,body.fl-dark .fl-material .fl-message,html.fl-dark .fl-material .fl-message{color:var(--md-text-secondary-dark)}.fl-material.fl-auto-dark .fl-action-button:focus,.fl-material.fl-auto-dark .fl-action-button:hover,body.fl-dark .fl-material .fl-action-button:focus,body.fl-dark .fl-material .fl-action-button:hover,html.fl-dark .fl-material .fl-action-button:focus,html.fl-dark .fl-material .fl-action-button:hover{background-color:hsla(0,0%,100%,.08)}
|
||||
@@ -0,0 +1 @@
|
||||
!function(e,s){"object"==typeof exports&&"undefined"!=typeof module?s(require("@flasher/flasher")):"function"==typeof define&&define.amd?define(["@flasher/flasher"],s):s((e="undefined"!=typeof globalThis?globalThis:e||self).flasher)}(this,(function(e){"use strict";e.addTheme("material",{render:e=>{const{type:s,message:n}=e,a="error"===s||"warning"===s;return`\n <div class="fl-material fl-${s}" role="${a?"alert":"status"}" aria-live="${a?"assertive":"polite"}" aria-atomic="true">\n <div class="fl-md-card">\n <div class="fl-content">\n <div class="fl-text-content">\n <div class="fl-message">${n}</div>\n </div>\n </div>\n <div class="fl-actions">\n <button class="fl-action-button fl-close" aria-label="Close ${s} message">\n DISMISS\n </button>\n </div>\n </div>\n <div class="fl-progress-bar">\n <div class="fl-progress"></div>\n </div>\n </div>`}})}));
|
||||
@@ -0,0 +1 @@
|
||||
.fl-minimal{--minimal-bg-light:#fff;--minimal-bg-dark:#191919;--minimal-text-light:#333;--minimal-text-dark:#f5f5f5;--minimal-shadow:0 2px 8px rgba(0,0,0,.08);--minimal-shadow-dark:0 2px 8px rgba(0,0,0,.15);--minimal-border-radius:4px;--minimal-border-color:rgba(0,0,0,.05);--minimal-border-color-dark:hsla(0,0%,100%,.1);--minimal-success:rgba(34,197,94,.9);--minimal-info:rgba(14,165,233,.9);--minimal-warning:rgba(245,158,11,.9);--minimal-error:rgba(239,68,68,.9)}@keyframes minimalIn{0%{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}.fl-minimal{animation:minimalIn .2s ease-out;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);background-color:var(--minimal-bg-light);border:1px solid var(--minimal-border-color);border-radius:var(--minimal-border-radius);box-shadow:var(--minimal-shadow);color:var(--minimal-text-light);font-family:-apple-system,BlinkMacSystemFont,var(--fl-font),sans-serif;margin:.5rem 0;padding:.75rem 1rem;position:relative;will-change:transform,opacity}.fl-minimal .fl-content{align-items:center;display:flex;gap:.75rem}.fl-minimal .fl-dot{border-radius:50%;flex-shrink:0;height:8px;width:8px}.fl-minimal .fl-message{flex:1;font-size:.875rem;font-weight:450;line-height:1.4;margin:0}.fl-minimal .fl-close{align-items:center;background:none;border:none;color:currentColor;cursor:pointer;display:flex;flex-shrink:0;font-size:1rem;height:1.5rem;justify-content:center;opacity:.5;padding:.25rem;transition:opacity .15s;width:1.5rem}.fl-minimal .fl-close:focus,.fl-minimal .fl-close:hover{opacity:.8}.fl-minimal .fl-progress-bar{border-radius:0 0 var(--minimal-border-radius) var(--minimal-border-radius);bottom:0;height:2px;left:0;opacity:.7;overflow:hidden;position:absolute;right:0}.fl-minimal .fl-progress-bar .fl-progress{height:100%;width:100%}.fl-minimal.fl-success .fl-dot,.fl-minimal.fl-success .fl-progress-bar .fl-progress{background-color:var(--minimal-success)}.fl-minimal.fl-info .fl-dot,.fl-minimal.fl-info .fl-progress-bar .fl-progress{background-color:var(--minimal-info)}.fl-minimal.fl-warning .fl-dot,.fl-minimal.fl-warning .fl-progress-bar .fl-progress{background-color:var(--minimal-warning)}.fl-minimal.fl-error .fl-dot,.fl-minimal.fl-error .fl-progress-bar .fl-progress{background-color:var(--minimal-error)}.fl-minimal.fl-rtl{direction:rtl}.fl-minimal.fl-rtl .fl-progress .fl-progress{transform-origin:right center}@media (prefers-reduced-motion:reduce){.fl-minimal{animation:none}}.fl-minimal.fl-auto-dark,body.fl-dark .fl-minimal,html.fl-dark .fl-minimal{background-color:var(--minimal-bg-dark);border-color:var(--minimal-border-color-dark);box-shadow:var(--minimal-shadow-dark);color:var(--minimal-text-dark)}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user