wasm-cli 0.13.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- wasm_cli-0.13.4/LICENSE +102 -0
- wasm_cli-0.13.4/PKG-INFO +609 -0
- wasm_cli-0.13.4/README.md +546 -0
- wasm_cli-0.13.4/pyproject.toml +164 -0
- wasm_cli-0.13.4/setup.cfg +4 -0
- wasm_cli-0.13.4/setup.py +43 -0
- wasm_cli-0.13.4/src/wasm/__init__.py +24 -0
- wasm_cli-0.13.4/src/wasm/__main__.py +8 -0
- wasm_cli-0.13.4/src/wasm/cli/__init__.py +6 -0
- wasm_cli-0.13.4/src/wasm/cli/commands/__init__.py +19 -0
- wasm_cli-0.13.4/src/wasm/cli/commands/backup.py +480 -0
- wasm_cli-0.13.4/src/wasm/cli/commands/cert.py +237 -0
- wasm_cli-0.13.4/src/wasm/cli/commands/db.py +1009 -0
- wasm_cli-0.13.4/src/wasm/cli/commands/monitor.py +382 -0
- wasm_cli-0.13.4/src/wasm/cli/commands/service.py +203 -0
- wasm_cli-0.13.4/src/wasm/cli/commands/setup.py +1042 -0
- wasm_cli-0.13.4/src/wasm/cli/commands/site.py +231 -0
- wasm_cli-0.13.4/src/wasm/cli/commands/store.py +386 -0
- wasm_cli-0.13.4/src/wasm/cli/commands/web.py +665 -0
- wasm_cli-0.13.4/src/wasm/cli/commands/webapp.py +606 -0
- wasm_cli-0.13.4/src/wasm/cli/interactive.py +613 -0
- wasm_cli-0.13.4/src/wasm/cli/parser.py +1656 -0
- wasm_cli-0.13.4/src/wasm/completions/__init__.py +31 -0
- wasm_cli-0.13.4/src/wasm/completions/_wasm +392 -0
- wasm_cli-0.13.4/src/wasm/completions/wasm.bash +445 -0
- wasm_cli-0.13.4/src/wasm/completions/wasm.fish +266 -0
- wasm_cli-0.13.4/src/wasm/core/__init__.py +35 -0
- wasm_cli-0.13.4/src/wasm/core/config.py +297 -0
- wasm_cli-0.13.4/src/wasm/core/dependencies.py +606 -0
- wasm_cli-0.13.4/src/wasm/core/exceptions.py +240 -0
- wasm_cli-0.13.4/src/wasm/core/logger.py +376 -0
- wasm_cli-0.13.4/src/wasm/core/store.py +1090 -0
- wasm_cli-0.13.4/src/wasm/core/utils.py +526 -0
- wasm_cli-0.13.4/src/wasm/deployers/__init__.py +11 -0
- wasm_cli-0.13.4/src/wasm/deployers/base.py +1177 -0
- wasm_cli-0.13.4/src/wasm/deployers/nextjs.py +148 -0
- wasm_cli-0.13.4/src/wasm/deployers/nodejs.py +128 -0
- wasm_cli-0.13.4/src/wasm/deployers/python.py +221 -0
- wasm_cli-0.13.4/src/wasm/deployers/registry.py +143 -0
- wasm_cli-0.13.4/src/wasm/deployers/static.py +214 -0
- wasm_cli-0.13.4/src/wasm/deployers/vite.py +187 -0
- wasm_cli-0.13.4/src/wasm/main.py +140 -0
- wasm_cli-0.13.4/src/wasm/managers/__init__.py +21 -0
- wasm_cli-0.13.4/src/wasm/managers/apache_manager.py +405 -0
- wasm_cli-0.13.4/src/wasm/managers/backup_manager.py +964 -0
- wasm_cli-0.13.4/src/wasm/managers/base_manager.py +111 -0
- wasm_cli-0.13.4/src/wasm/managers/cert_manager.py +475 -0
- wasm_cli-0.13.4/src/wasm/managers/database/__init__.py +32 -0
- wasm_cli-0.13.4/src/wasm/managers/database/base.py +665 -0
- wasm_cli-0.13.4/src/wasm/managers/database/mongodb.py +595 -0
- wasm_cli-0.13.4/src/wasm/managers/database/mysql.py +598 -0
- wasm_cli-0.13.4/src/wasm/managers/database/postgres.py +570 -0
- wasm_cli-0.13.4/src/wasm/managers/database/redis.py +626 -0
- wasm_cli-0.13.4/src/wasm/managers/database/registry.py +119 -0
- wasm_cli-0.13.4/src/wasm/managers/nginx_manager.py +376 -0
- wasm_cli-0.13.4/src/wasm/managers/service_manager.py +472 -0
- wasm_cli-0.13.4/src/wasm/managers/source_manager.py +579 -0
- wasm_cli-0.13.4/src/wasm/monitor/__init__.py +16 -0
- wasm_cli-0.13.4/src/wasm/monitor/ai_analyzer.py +630 -0
- wasm_cli-0.13.4/src/wasm/monitor/email_notifier.py +629 -0
- wasm_cli-0.13.4/src/wasm/monitor/process_monitor.py +1006 -0
- wasm_cli-0.13.4/src/wasm/templates/__init__.py +1 -0
- wasm_cli-0.13.4/src/wasm/templates/apache/proxy.conf.j2 +56 -0
- wasm_cli-0.13.4/src/wasm/templates/apache/static.conf.j2 +68 -0
- wasm_cli-0.13.4/src/wasm/templates/nginx/proxy.conf.j2 +96 -0
- wasm_cli-0.13.4/src/wasm/templates/nginx/static.conf.j2 +80 -0
- wasm_cli-0.13.4/src/wasm/templates/systemd/app.service.j2 +40 -0
- wasm_cli-0.13.4/src/wasm/validators/__init__.py +32 -0
- wasm_cli-0.13.4/src/wasm/validators/domain.py +182 -0
- wasm_cli-0.13.4/src/wasm/validators/port.py +225 -0
- wasm_cli-0.13.4/src/wasm/validators/source.py +333 -0
- wasm_cli-0.13.4/src/wasm/validators/ssh.py +416 -0
- wasm_cli-0.13.4/src/wasm/web/__init__.py +15 -0
- wasm_cli-0.13.4/src/wasm/web/api/__init__.py +7 -0
- wasm_cli-0.13.4/src/wasm/web/api/apps.py +422 -0
- wasm_cli-0.13.4/src/wasm/web/api/auth.py +157 -0
- wasm_cli-0.13.4/src/wasm/web/api/backups.py +333 -0
- wasm_cli-0.13.4/src/wasm/web/api/certs.py +368 -0
- wasm_cli-0.13.4/src/wasm/web/api/config.py +360 -0
- wasm_cli-0.13.4/src/wasm/web/api/databases.py +815 -0
- wasm_cli-0.13.4/src/wasm/web/api/jobs.py +320 -0
- wasm_cli-0.13.4/src/wasm/web/api/monitor.py +461 -0
- wasm_cli-0.13.4/src/wasm/web/api/router.py +32 -0
- wasm_cli-0.13.4/src/wasm/web/api/services.py +492 -0
- wasm_cli-0.13.4/src/wasm/web/api/sites.py +522 -0
- wasm_cli-0.13.4/src/wasm/web/api/system.py +434 -0
- wasm_cli-0.13.4/src/wasm/web/auth.py +546 -0
- wasm_cli-0.13.4/src/wasm/web/jobs.py +690 -0
- wasm_cli-0.13.4/src/wasm/web/server.py +440 -0
- wasm_cli-0.13.4/src/wasm/web/static/css/main.css +904 -0
- wasm_cli-0.13.4/src/wasm/web/static/index.html +2054 -0
- wasm_cli-0.13.4/src/wasm/web/static/js/components/cards.js +396 -0
- wasm_cli-0.13.4/src/wasm/web/static/js/components/jobs.js +145 -0
- wasm_cli-0.13.4/src/wasm/web/static/js/components/metrics.js +262 -0
- wasm_cli-0.13.4/src/wasm/web/static/js/components/skeleton.js +172 -0
- wasm_cli-0.13.4/src/wasm/web/static/js/core/api.js +261 -0
- wasm_cli-0.13.4/src/wasm/web/static/js/core/dialogs.js +208 -0
- wasm_cli-0.13.4/src/wasm/web/static/js/core/notifications.js +249 -0
- wasm_cli-0.13.4/src/wasm/web/static/js/core/router.js +158 -0
- wasm_cli-0.13.4/src/wasm/web/static/js/core/search.js +365 -0
- wasm_cli-0.13.4/src/wasm/web/static/js/core/shortcuts.js +210 -0
- wasm_cli-0.13.4/src/wasm/web/static/js/core/theme.js +129 -0
- wasm_cli-0.13.4/src/wasm/web/static/js/core/ui.js +303 -0
- wasm_cli-0.13.4/src/wasm/web/static/js/core/websocket.js +172 -0
- wasm_cli-0.13.4/src/wasm/web/static/js/main.js +187 -0
- wasm_cli-0.13.4/src/wasm/web/static/js/pages/apps.js +218 -0
- wasm_cli-0.13.4/src/wasm/web/static/js/pages/backups.js +387 -0
- wasm_cli-0.13.4/src/wasm/web/static/js/pages/certs.js +152 -0
- wasm_cli-0.13.4/src/wasm/web/static/js/pages/config.js +494 -0
- wasm_cli-0.13.4/src/wasm/web/static/js/pages/dashboard.js +210 -0
- wasm_cli-0.13.4/src/wasm/web/static/js/pages/databases.js +1108 -0
- wasm_cli-0.13.4/src/wasm/web/static/js/pages/jobs.js +230 -0
- wasm_cli-0.13.4/src/wasm/web/static/js/pages/logs.js +111 -0
- wasm_cli-0.13.4/src/wasm/web/static/js/pages/monitor.js +475 -0
- wasm_cli-0.13.4/src/wasm/web/static/js/pages/services.js +338 -0
- wasm_cli-0.13.4/src/wasm/web/static/js/pages/sites.js +305 -0
- wasm_cli-0.13.4/src/wasm/web/static/login.html +293 -0
- wasm_cli-0.13.4/src/wasm/web/static/logo.png +0 -0
- wasm_cli-0.13.4/src/wasm/web/static/logo.webp +0 -0
- wasm_cli-0.13.4/src/wasm/web/websockets/__init__.py +7 -0
- wasm_cli-0.13.4/src/wasm/web/websockets/router.py +673 -0
- wasm_cli-0.13.4/src/wasm_cli.egg-info/PKG-INFO +609 -0
- wasm_cli-0.13.4/src/wasm_cli.egg-info/SOURCES.txt +134 -0
- wasm_cli-0.13.4/src/wasm_cli.egg-info/dependency_links.txt +1 -0
- wasm_cli-0.13.4/src/wasm_cli.egg-info/entry_points.txt +2 -0
- wasm_cli-0.13.4/src/wasm_cli.egg-info/requires.txt +36 -0
- wasm_cli-0.13.4/src/wasm_cli.egg-info/top_level.txt +1 -0
- wasm_cli-0.13.4/tests/test_backup.py +564 -0
- wasm_cli-0.13.4/tests/test_dependencies.py +209 -0
- wasm_cli-0.13.4/tests/test_logger.py +126 -0
- wasm_cli-0.13.4/tests/test_port.py +156 -0
- wasm_cli-0.13.4/tests/test_source.py +154 -0
- wasm_cli-0.13.4/tests/test_ssh.py +84 -0
- wasm_cli-0.13.4/tests/test_store.py +561 -0
- wasm_cli-0.13.4/tests/test_validators.py +124 -0
- wasm_cli-0.13.4/tests/test_web_ui.py +447 -0
wasm_cli-0.13.4/LICENSE
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
WASM Non-Commercial Source-Available License (WASM-NCSAL)
|
|
2
|
+
Version 1.0
|
|
3
|
+
|
|
4
|
+
Copyright (c) 2024-2025 Yago López Prado
|
|
5
|
+
|
|
6
|
+
TERMS AND CONDITIONS
|
|
7
|
+
|
|
8
|
+
1. DEFINITIONS
|
|
9
|
+
|
|
10
|
+
"Software" refers to WASM (Web App System Management) and all associated
|
|
11
|
+
source code, documentation, and related materials.
|
|
12
|
+
|
|
13
|
+
"Author" refers to Yago López Prado.
|
|
14
|
+
|
|
15
|
+
"Commercial Use" means any use of the Software that directly or indirectly
|
|
16
|
+
generates revenue or provides business value, including but not limited to:
|
|
17
|
+
selling the Software, incorporating it into paid products or services, using
|
|
18
|
+
it in commercial operations, deploying it in business environments to reduce
|
|
19
|
+
costs or increase efficiency, or any form of monetization or business
|
|
20
|
+
advantage whatsoever.
|
|
21
|
+
|
|
22
|
+
2. GRANT OF RIGHTS
|
|
23
|
+
|
|
24
|
+
Subject to the terms of this License, the Author hereby grants you a
|
|
25
|
+
worldwide, royalty-free, non-exclusive license to:
|
|
26
|
+
|
|
27
|
+
a) Use the Software for personal and educational purposes only
|
|
28
|
+
b) Study, modify, and adapt the Software
|
|
29
|
+
c) Distribute copies of the Software
|
|
30
|
+
d) Contribute improvements back to the project
|
|
31
|
+
|
|
32
|
+
3. CONDITIONS
|
|
33
|
+
|
|
34
|
+
The above rights are granted provided that:
|
|
35
|
+
|
|
36
|
+
a) You include this License and copyright notice in all copies or substantial
|
|
37
|
+
portions of the Software
|
|
38
|
+
b) You do not use the Software for Commercial Use without prior written
|
|
39
|
+
authorization from the Author
|
|
40
|
+
c) You do not claim ownership or authorship of the original Software
|
|
41
|
+
d) Any modifications must be clearly marked as such and not misrepresented
|
|
42
|
+
as the original Software
|
|
43
|
+
|
|
44
|
+
4. COMMERCIAL USE PROHIBITION
|
|
45
|
+
|
|
46
|
+
Commercial Use of this Software is strictly prohibited without prior written
|
|
47
|
+
agreement with the Author. This includes but is not limited to:
|
|
48
|
+
|
|
49
|
+
- Selling the Software or any derivative works
|
|
50
|
+
- Including the Software in paid products or services
|
|
51
|
+
- Using the Software to provide paid services to third parties
|
|
52
|
+
- Using the Software in business environments to reduce costs or gain
|
|
53
|
+
competitive advantages
|
|
54
|
+
- Any form of monetization, appropriation, or business benefit from the
|
|
55
|
+
Software
|
|
56
|
+
|
|
57
|
+
5. OBTAINING COMMERCIAL LICENSE
|
|
58
|
+
|
|
59
|
+
If you wish to use this Software for Commercial purposes, you must contact
|
|
60
|
+
the Author to discuss licensing terms and reach a commercial agreement:
|
|
61
|
+
|
|
62
|
+
Email: yago.lopez.adeje@gmail.com
|
|
63
|
+
hello@bitbeet.dev
|
|
64
|
+
Phone: +34 637 881 066
|
|
65
|
+
|
|
66
|
+
6. CONTRIBUTIONS
|
|
67
|
+
|
|
68
|
+
Contributions to this project are welcome and encouraged. By submitting
|
|
69
|
+
contributions, you agree that:
|
|
70
|
+
|
|
71
|
+
a) Your contributions will be licensed under the same terms as this License
|
|
72
|
+
b) You have the right to submit the contribution
|
|
73
|
+
c) You grant the Author a perpetual, worldwide, non-exclusive, royalty-free,
|
|
74
|
+
irrevocable, sublicensable license to use, reproduce, modify, distribute,
|
|
75
|
+
and commercialize your contributions in any way, including in commercial
|
|
76
|
+
versions of the Software
|
|
77
|
+
d) The Author is not obligated to include your contributions in the Software
|
|
78
|
+
|
|
79
|
+
7. DISCLAIMER OF WARRANTY
|
|
80
|
+
|
|
81
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
82
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
83
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
84
|
+
AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
85
|
+
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
86
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
87
|
+
|
|
88
|
+
8. LIMITATION OF LIABILITY
|
|
89
|
+
|
|
90
|
+
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT,
|
|
91
|
+
OR CONSEQUENTIAL DAMAGES WHATSOEVER ARISING OUT OF THE USE OF OR INABILITY
|
|
92
|
+
TO USE THE SOFTWARE.
|
|
93
|
+
|
|
94
|
+
9. TERMINATION
|
|
95
|
+
|
|
96
|
+
This License automatically terminates if you violate any of its terms. Upon
|
|
97
|
+
termination, you must destroy all copies of the Software in your possession.
|
|
98
|
+
|
|
99
|
+
10. GOVERNING LAW
|
|
100
|
+
|
|
101
|
+
This License shall be governed by and construed in accordance with the laws
|
|
102
|
+
of Spain, without regard to its conflict of laws provisions.
|
wasm_cli-0.13.4/PKG-INFO
ADDED
|
@@ -0,0 +1,609 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: wasm-cli
|
|
3
|
+
Version: 0.13.4
|
|
4
|
+
Summary: Web App System Management - Deploy and manage web applications on Linux servers
|
|
5
|
+
Author: Yago López Prado
|
|
6
|
+
Author-email: Yago López Prado <yago.lopez.adeje@gmail.com>
|
|
7
|
+
License: WASM-NCSAL
|
|
8
|
+
Project-URL: Homepage, https://github.com/Perkybeet/wasm
|
|
9
|
+
Project-URL: Documentation, https://github.com/Perkybeet/wasm#readme
|
|
10
|
+
Project-URL: Repository, https://github.com/Perkybeet/wasm.git
|
|
11
|
+
Project-URL: Bug Tracker, https://github.com/Perkybeet/wasm/issues
|
|
12
|
+
Keywords: cli,deployment,nginx,apache,systemd,web-apps,server-management,certbot,ssl
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Environment :: Console
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Intended Audience :: System Administrators
|
|
17
|
+
Classifier: License :: Other/Proprietary License
|
|
18
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
19
|
+
Classifier: Programming Language :: Python :: 3
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Topic :: System :: Installation/Setup
|
|
24
|
+
Classifier: Topic :: System :: Systems Administration
|
|
25
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
|
|
26
|
+
Requires-Python: >=3.10
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
License-File: LICENSE
|
|
29
|
+
Requires-Dist: inquirer>=3.1.0
|
|
30
|
+
Requires-Dist: Jinja2>=3.1.0
|
|
31
|
+
Requires-Dist: PyYAML>=6.0
|
|
32
|
+
Provides-Extra: dev
|
|
33
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
34
|
+
Requires-Dist: pytest-cov>=4.0; extra == "dev"
|
|
35
|
+
Requires-Dist: black>=23.0; extra == "dev"
|
|
36
|
+
Requires-Dist: isort>=5.12; extra == "dev"
|
|
37
|
+
Requires-Dist: mypy>=1.0; extra == "dev"
|
|
38
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
39
|
+
Provides-Extra: rich
|
|
40
|
+
Requires-Dist: rich>=13.0; extra == "rich"
|
|
41
|
+
Provides-Extra: monitor
|
|
42
|
+
Requires-Dist: psutil>=5.9.0; extra == "monitor"
|
|
43
|
+
Requires-Dist: httpx>=0.25.0; extra == "monitor"
|
|
44
|
+
Provides-Extra: web
|
|
45
|
+
Requires-Dist: fastapi>=0.109.0; extra == "web"
|
|
46
|
+
Requires-Dist: uvicorn[standard]>=0.27.0; extra == "web"
|
|
47
|
+
Requires-Dist: python-jose[cryptography]>=3.3.0; extra == "web"
|
|
48
|
+
Requires-Dist: passlib[bcrypt]>=1.7.4; extra == "web"
|
|
49
|
+
Requires-Dist: psutil>=5.9.0; extra == "web"
|
|
50
|
+
Requires-Dist: aiofiles>=23.0.0; extra == "web"
|
|
51
|
+
Provides-Extra: all
|
|
52
|
+
Requires-Dist: rich>=13.0; extra == "all"
|
|
53
|
+
Requires-Dist: psutil>=5.9.0; extra == "all"
|
|
54
|
+
Requires-Dist: httpx>=0.25.0; extra == "all"
|
|
55
|
+
Requires-Dist: fastapi>=0.109.0; extra == "all"
|
|
56
|
+
Requires-Dist: uvicorn[standard]>=0.27.0; extra == "all"
|
|
57
|
+
Requires-Dist: python-jose[cryptography]>=3.3.0; extra == "all"
|
|
58
|
+
Requires-Dist: passlib[bcrypt]>=1.7.4; extra == "all"
|
|
59
|
+
Requires-Dist: aiofiles>=23.0.0; extra == "all"
|
|
60
|
+
Dynamic: author
|
|
61
|
+
Dynamic: license-file
|
|
62
|
+
Dynamic: requires-python
|
|
63
|
+
|
|
64
|
+
# WASM - Web App System Management
|
|
65
|
+
|
|
66
|
+
<p align="center">
|
|
67
|
+
<img src="docs/assets/logo_bg.png" alt="WASM Logo" width="400">
|
|
68
|
+
</p>
|
|
69
|
+
|
|
70
|
+
<p align="center">
|
|
71
|
+
<strong>Deploy, manage, and monitor web applications with ease</strong>
|
|
72
|
+
</p>
|
|
73
|
+
|
|
74
|
+
<p align="center">
|
|
75
|
+
<a href="https://build.opensuse.org/package/show/home:Perkybeet/wasm">
|
|
76
|
+
<img src="https://build.opensuse.org/projects/home:Perkybeet/packages/wasm/badge.svg?type=default" alt="OBS Build Status">
|
|
77
|
+
</a>
|
|
78
|
+
<a href="https://pypi.org/project/wasm-cli/">
|
|
79
|
+
<img src="https://img.shields.io/pypi/v/wasm-cli?color=blue&logo=pypi&logoColor=white" alt="PyPI Version">
|
|
80
|
+
</a>
|
|
81
|
+
<a href="https://pypi.org/project/wasm-cli/">
|
|
82
|
+
<img src="https://img.shields.io/pypi/pyversions/wasm-cli?logo=python&logoColor=white" alt="Python Version">
|
|
83
|
+
</a>
|
|
84
|
+
<a href="https://github.com/Perkybeet/wasm/blob/main/LICENSE">
|
|
85
|
+
<img src="https://img.shields.io/github/license/Perkybeet/wasm?color=blue" alt="License">
|
|
86
|
+
</a>
|
|
87
|
+
<a href="https://github.com/Perkybeet/wasm/stargazers">
|
|
88
|
+
<img src="https://img.shields.io/github/stars/Perkybeet/wasm?style=social" alt="GitHub Stars">
|
|
89
|
+
</a>
|
|
90
|
+
<a href="https://pypi.org/project/wasm-cli/">
|
|
91
|
+
<img src="https://img.shields.io/pypi/dm/wasm-cli?color=blue&logo=pypi" alt="PyPI Downloads">
|
|
92
|
+
</a>
|
|
93
|
+
<a href="https://github.com/Perkybeet/wasm/issues">
|
|
94
|
+
<img src="https://img.shields.io/github/issues/Perkybeet/wasm" alt="GitHub Issues">
|
|
95
|
+
</a>
|
|
96
|
+
</p>
|
|
97
|
+
|
|
98
|
+
<p align="center">
|
|
99
|
+
<a href="#installation">Installation</a> •
|
|
100
|
+
<a href="#quick-start">Quick Start</a> •
|
|
101
|
+
<a href="#features">Features</a> •
|
|
102
|
+
<a href="#documentation">Documentation</a>
|
|
103
|
+
</p>
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## 🚀 What is WASM?
|
|
108
|
+
|
|
109
|
+
**WASM (Web App System Management)** is a powerful CLI tool designed to simplify the deployment and management of web applications on Linux servers. It automates the entire process from cloning your code to serving it with Nginx/Apache, including SSL certificates and systemd services.
|
|
110
|
+
|
|
111
|
+
### Key Capabilities
|
|
112
|
+
|
|
113
|
+
- 🌐 **Site Management** - Create and manage Nginx/Apache virtual hosts
|
|
114
|
+
- 🔒 **SSL Certificates** - Automated Let's Encrypt certificates via Certbot
|
|
115
|
+
- ⚙️ **Service Management** - Create and control systemd services
|
|
116
|
+
- 🚀 **One-Command Deployment** - Deploy full-stack applications instantly
|
|
117
|
+
- 🎯 **Multi-Framework Support** - Next.js, Node.js, Vite, Python, and more
|
|
118
|
+
- 🧭 **Interactive Mode** - Guided step-by-step deployment wizard
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## 📦 Installation
|
|
123
|
+
|
|
124
|
+
### Ubuntu/Debian - From OBS Repository (Recommended)
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
# Add repository key
|
|
128
|
+
curl -fsSL https://download.opensuse.org/repositories/home:/Perkybeet/xUbuntu_24.04/Release.key | \
|
|
129
|
+
gpg --dearmor | sudo tee /usr/share/keyrings/wasm.gpg > /dev/null
|
|
130
|
+
|
|
131
|
+
# Add repository (Ubuntu 24.04)
|
|
132
|
+
echo 'deb [signed-by=/usr/share/keyrings/wasm.gpg] https://download.opensuse.org/repositories/home:/Perkybeet/xUbuntu_24.04/ /' | \
|
|
133
|
+
sudo tee /etc/apt/sources.list.d/wasm.list
|
|
134
|
+
|
|
135
|
+
# Install
|
|
136
|
+
sudo apt update
|
|
137
|
+
sudo apt install wasm
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Supported Ubuntu versions:
|
|
141
|
+
- Ubuntu 22.04 LTS (Jammy Jellyfish)
|
|
142
|
+
- Ubuntu 24.04 LTS (Noble Numbat)
|
|
143
|
+
|
|
144
|
+
### Fedora - From OBS Repository
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
# Add repository
|
|
148
|
+
sudo dnf config-manager --add-repo \
|
|
149
|
+
https://download.opensuse.org/repositories/home:/Perkybeet/Fedora_40/home:Perkybeet.repo
|
|
150
|
+
|
|
151
|
+
# Install
|
|
152
|
+
sudo dnf install wasm-cli
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### openSUSE - From OBS Repository
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
# Tumbleweed
|
|
159
|
+
sudo zypper ar -f \
|
|
160
|
+
https://download.opensuse.org/repositories/home:/Perkybeet/openSUSE_Tumbleweed/ \
|
|
161
|
+
home_Perkybeet
|
|
162
|
+
sudo zypper install wasm-cli
|
|
163
|
+
|
|
164
|
+
# Leap 15.6
|
|
165
|
+
sudo zypper ar -f \
|
|
166
|
+
https://download.opensuse.org/repositories/home:/Perkybeet/openSUSE_Leap_15.6/ \
|
|
167
|
+
home_Perkybeet
|
|
168
|
+
sudo zypper install wasm-cli
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Debian - From OBS Repository
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
# Add repository key
|
|
175
|
+
curl -fsSL https://download.opensuse.org/repositories/home:/Perkybeet/Debian_12/Release.key | \
|
|
176
|
+
gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/home_Perkybeet.gpg > /dev/null
|
|
177
|
+
|
|
178
|
+
# Add repository
|
|
179
|
+
echo 'deb https://download.opensuse.org/repositories/home:/Perkybeet/Debian_12/ /' | \
|
|
180
|
+
sudo tee /etc/apt/sources.list.d/home_Perkybeet.list
|
|
181
|
+
|
|
182
|
+
# Install
|
|
183
|
+
sudo apt update
|
|
184
|
+
sudo apt install wasm-cli
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### From .deb Package (GitHub Release)
|
|
188
|
+
|
|
189
|
+
Download the latest `.deb` from the [GitHub Releases](https://github.com/Perkybeet/wasm/releases/latest) page:
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
# Download latest version (check releases page for current version)
|
|
193
|
+
VERSION=$(curl -s https://api.github.com/repos/Perkybeet/wasm/releases/latest | grep -oP '"tag_name": "v\K[^"]+')
|
|
194
|
+
wget "https://github.com/Perkybeet/wasm/releases/latest/download/wasm_${VERSION}_all.deb"
|
|
195
|
+
sudo dpkg -i "wasm_${VERSION}_all.deb"
|
|
196
|
+
sudo apt install -f # Install dependencies if needed
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Or manually download from: **https://github.com/Perkybeet/wasm/releases/latest**
|
|
200
|
+
|
|
201
|
+
### From PyPI
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
pip install wasm-cli
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### From Source
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
git clone https://github.com/Perkybeet/wasm.git
|
|
211
|
+
cd wasm
|
|
212
|
+
pip install -e .
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## 🏃 Quick Start
|
|
218
|
+
|
|
219
|
+
### Deploy a Next.js Application
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
# One-liner deployment
|
|
223
|
+
wasm webapp create \
|
|
224
|
+
--domain myapp.example.com \
|
|
225
|
+
--source git@github.com:user/my-nextjs-app.git \
|
|
226
|
+
--type nextjs \
|
|
227
|
+
--port 3000
|
|
228
|
+
|
|
229
|
+
# Short version
|
|
230
|
+
wasm wp create -d myapp.example.com -s git@github.com:user/app.git -t nextjs -p 3000
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Interactive Mode
|
|
234
|
+
|
|
235
|
+
For a guided experience, simply run:
|
|
236
|
+
|
|
237
|
+
```bash
|
|
238
|
+
wasm
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
Or explicitly:
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
wasm --interactive
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
You'll be guided through all the options step by step:
|
|
248
|
+
|
|
249
|
+
```
|
|
250
|
+
┌─────────────────────────────────────────────────┐
|
|
251
|
+
│ WASM - Web App System Management │
|
|
252
|
+
└─────────────────────────────────────────────────┘
|
|
253
|
+
|
|
254
|
+
? What would you like to do?
|
|
255
|
+
❯ 🚀 Deploy a Web Application
|
|
256
|
+
🌐 Manage Sites (Nginx/Apache)
|
|
257
|
+
⚙️ Manage Services
|
|
258
|
+
🔒 Manage SSL Certificates
|
|
259
|
+
📊 View Status Dashboard
|
|
260
|
+
⚡ Exit
|
|
261
|
+
|
|
262
|
+
? Select application type:
|
|
263
|
+
❯ Next.js
|
|
264
|
+
Node.js (Express, Fastify, etc.)
|
|
265
|
+
Vite (React, Vue, Svelte)
|
|
266
|
+
Python (Django, Flask, FastAPI)
|
|
267
|
+
Static Site
|
|
268
|
+
Custom
|
|
269
|
+
|
|
270
|
+
? Enter the domain name: myapp.example.com
|
|
271
|
+
? Enter the source (Git URL or path): git@github.com:user/app.git
|
|
272
|
+
? Enter the port number: 3000
|
|
273
|
+
? Configure SSL certificate? Yes
|
|
274
|
+
|
|
275
|
+
[1/7] 📥 Cloning repository...
|
|
276
|
+
[2/7] 📦 Installing dependencies...
|
|
277
|
+
[3/7] 🔨 Building application...
|
|
278
|
+
[4/7] 🌐 Creating Nginx configuration...
|
|
279
|
+
[5/7] 🔒 Obtaining SSL certificate...
|
|
280
|
+
[6/7] ⚙️ Creating systemd service...
|
|
281
|
+
[7/7] 🚀 Starting application...
|
|
282
|
+
|
|
283
|
+
✅ Deployment complete!
|
|
284
|
+
|
|
285
|
+
URL: https://myapp.example.com
|
|
286
|
+
Status: Running
|
|
287
|
+
Service: wasm-myapp-example-com
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## 📋 Features
|
|
293
|
+
|
|
294
|
+
### Web Application Deployment
|
|
295
|
+
|
|
296
|
+
```bash
|
|
297
|
+
# Create a new web application
|
|
298
|
+
wasm webapp create [options]
|
|
299
|
+
|
|
300
|
+
Options:
|
|
301
|
+
-d, --domain DOMAIN Target domain (e.g., example.com)
|
|
302
|
+
-s, --source SOURCE Git URL or local path to source code
|
|
303
|
+
-t, --type TYPE Application type (nextjs, nodejs, vite, python, static)
|
|
304
|
+
-p, --port PORT Application port (default: auto-assigned)
|
|
305
|
+
-w, --webserver SERVER Web server (nginx, apache) [default: nginx]
|
|
306
|
+
--no-ssl Skip SSL certificate configuration
|
|
307
|
+
--branch BRANCH Git branch to deploy [default: main]
|
|
308
|
+
--env-file FILE Path to .env file to use
|
|
309
|
+
-v, --verbose Enable verbose output
|
|
310
|
+
|
|
311
|
+
# List deployed applications
|
|
312
|
+
wasm webapp list
|
|
313
|
+
|
|
314
|
+
# Get application status
|
|
315
|
+
wasm webapp status myapp.example.com
|
|
316
|
+
|
|
317
|
+
# Restart application
|
|
318
|
+
wasm webapp restart myapp.example.com
|
|
319
|
+
|
|
320
|
+
# Remove application
|
|
321
|
+
wasm webapp delete myapp.example.com
|
|
322
|
+
|
|
323
|
+
# Update application (pull & rebuild)
|
|
324
|
+
wasm webapp update myapp.example.com
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### Site Management
|
|
328
|
+
|
|
329
|
+
```bash
|
|
330
|
+
# Create a site (without deploying an app)
|
|
331
|
+
wasm site create -d example.com -w nginx
|
|
332
|
+
|
|
333
|
+
# List all sites
|
|
334
|
+
wasm site list
|
|
335
|
+
|
|
336
|
+
# Enable/disable site
|
|
337
|
+
wasm site enable example.com
|
|
338
|
+
wasm site disable example.com
|
|
339
|
+
|
|
340
|
+
# Delete site
|
|
341
|
+
wasm site delete example.com
|
|
342
|
+
|
|
343
|
+
# Show site configuration
|
|
344
|
+
wasm site show example.com
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
### Service Management
|
|
348
|
+
|
|
349
|
+
```bash
|
|
350
|
+
# Create a custom service
|
|
351
|
+
wasm service create --name myservice --command "/usr/bin/myapp" --user www-data
|
|
352
|
+
|
|
353
|
+
# List managed services
|
|
354
|
+
wasm service list
|
|
355
|
+
|
|
356
|
+
# Control services
|
|
357
|
+
wasm service start myservice
|
|
358
|
+
wasm service stop myservice
|
|
359
|
+
wasm service restart myservice
|
|
360
|
+
|
|
361
|
+
# View service status
|
|
362
|
+
wasm service status myservice
|
|
363
|
+
|
|
364
|
+
# View service logs
|
|
365
|
+
wasm service logs myservice
|
|
366
|
+
wasm service logs myservice --follow
|
|
367
|
+
wasm service logs myservice --lines 100
|
|
368
|
+
|
|
369
|
+
# Delete service
|
|
370
|
+
wasm service delete myservice
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
### SSL Certificate Management
|
|
374
|
+
|
|
375
|
+
```bash
|
|
376
|
+
# Obtain certificate for a domain
|
|
377
|
+
wasm cert create -d example.com
|
|
378
|
+
|
|
379
|
+
# List certificates
|
|
380
|
+
wasm cert list
|
|
381
|
+
|
|
382
|
+
# Renew all certificates
|
|
383
|
+
wasm cert renew
|
|
384
|
+
|
|
385
|
+
# Revoke a certificate
|
|
386
|
+
wasm cert revoke example.com
|
|
387
|
+
|
|
388
|
+
# Show certificate info
|
|
389
|
+
wasm cert info example.com
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
---
|
|
393
|
+
|
|
394
|
+
## 🎯 Supported Application Types
|
|
395
|
+
|
|
396
|
+
| Type | Framework | Auto-Detection |
|
|
397
|
+
|------|-----------|----------------|
|
|
398
|
+
| `nextjs` | Next.js | `next.config.js` |
|
|
399
|
+
| `nodejs` | Express, Fastify, Koa, etc. | `package.json` with start script |
|
|
400
|
+
| `vite` | React, Vue, Svelte (Vite) | `vite.config.js` |
|
|
401
|
+
| `python` | Django, Flask, FastAPI | `requirements.txt`, `pyproject.toml` |
|
|
402
|
+
| `static` | HTML/CSS/JS | `index.html` |
|
|
403
|
+
|
|
404
|
+
Each type has a specific deployment workflow that includes:
|
|
405
|
+
- Dependency installation
|
|
406
|
+
- Build process
|
|
407
|
+
- Environment configuration
|
|
408
|
+
- Service setup
|
|
409
|
+
- Health checks
|
|
410
|
+
|
|
411
|
+
---
|
|
412
|
+
|
|
413
|
+
## ⚙️ Configuration
|
|
414
|
+
|
|
415
|
+
### Global Configuration
|
|
416
|
+
|
|
417
|
+
Configuration file location: `/etc/wasm/config.yaml`
|
|
418
|
+
|
|
419
|
+
```yaml
|
|
420
|
+
# Default web server
|
|
421
|
+
webserver: nginx
|
|
422
|
+
|
|
423
|
+
# Default apps directory
|
|
424
|
+
apps_directory: /var/www/apps
|
|
425
|
+
|
|
426
|
+
# Default user for services
|
|
427
|
+
service_user: www-data
|
|
428
|
+
|
|
429
|
+
# SSL settings
|
|
430
|
+
ssl:
|
|
431
|
+
enabled: true
|
|
432
|
+
provider: certbot
|
|
433
|
+
email: admin@example.com
|
|
434
|
+
|
|
435
|
+
# Logging
|
|
436
|
+
logging:
|
|
437
|
+
level: info
|
|
438
|
+
file: /var/log/wasm/wasm.log
|
|
439
|
+
|
|
440
|
+
# Node.js settings
|
|
441
|
+
nodejs:
|
|
442
|
+
default_version: 20
|
|
443
|
+
use_nvm: false
|
|
444
|
+
|
|
445
|
+
# Python settings
|
|
446
|
+
python:
|
|
447
|
+
default_version: "3.11"
|
|
448
|
+
use_venv: true
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
### Per-Project Configuration
|
|
452
|
+
|
|
453
|
+
You can include a `.wasm.yaml` file in your project root:
|
|
454
|
+
|
|
455
|
+
```yaml
|
|
456
|
+
type: nextjs
|
|
457
|
+
port: 3000
|
|
458
|
+
build_command: npm run build
|
|
459
|
+
start_command: npm run start
|
|
460
|
+
env_vars:
|
|
461
|
+
NODE_ENV: production
|
|
462
|
+
health_check:
|
|
463
|
+
path: /api/health
|
|
464
|
+
timeout: 30
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
---
|
|
468
|
+
|
|
469
|
+
## 📊 Verbose Mode
|
|
470
|
+
|
|
471
|
+
Add `--verbose` or `-v` for detailed output:
|
|
472
|
+
|
|
473
|
+
```bash
|
|
474
|
+
wasm webapp create -d example.com -s git@github.com:user/app.git -t nextjs -v
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
**Verbose output example:**
|
|
478
|
+
|
|
479
|
+
```
|
|
480
|
+
[1/7] 📥 Cloning repository...
|
|
481
|
+
├─ Source: git@github.com:user/app.git
|
|
482
|
+
├─ Branch: main
|
|
483
|
+
├─ Target: /var/www/apps/example-com
|
|
484
|
+
└─ Completed in 4.2s
|
|
485
|
+
|
|
486
|
+
[2/7] 📦 Installing dependencies...
|
|
487
|
+
├─ Package manager: npm
|
|
488
|
+
├─ Command: npm ci --production=false
|
|
489
|
+
├─ Packages installed: 1,247
|
|
490
|
+
└─ Completed in 45.3s
|
|
491
|
+
|
|
492
|
+
[3/7] 🔨 Building application...
|
|
493
|
+
├─ Command: npm run build
|
|
494
|
+
├─ Output directory: .next
|
|
495
|
+
├─ Build size: 12.4 MB
|
|
496
|
+
└─ Completed in 32.1s
|
|
497
|
+
...
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
---
|
|
501
|
+
|
|
502
|
+
## 🗂️ Directory Structure
|
|
503
|
+
|
|
504
|
+
WASM organizes deployed applications as follows:
|
|
505
|
+
|
|
506
|
+
```
|
|
507
|
+
/var/www/apps/
|
|
508
|
+
├── example-com/
|
|
509
|
+
│ ├── current/ # Current deployment (symlink)
|
|
510
|
+
│ ├── releases/ # Previous releases (for rollback)
|
|
511
|
+
│ │ ├── 20241215120000/
|
|
512
|
+
│ │ └── 20241214150000/
|
|
513
|
+
│ ├── shared/ # Shared files (uploads, logs)
|
|
514
|
+
│ └── .env # Environment variables
|
|
515
|
+
│
|
|
516
|
+
└── another-app/
|
|
517
|
+
└── ...
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
---
|
|
521
|
+
|
|
522
|
+
## 🔧 Requirements
|
|
523
|
+
|
|
524
|
+
### System Requirements
|
|
525
|
+
|
|
526
|
+
- **OS:** Ubuntu 20.04+, Debian 11+
|
|
527
|
+
- **Python:** 3.10+
|
|
528
|
+
- **Privileges:** sudo access for service management
|
|
529
|
+
|
|
530
|
+
### Optional Dependencies
|
|
531
|
+
|
|
532
|
+
- **nginx** or **apache2** - Web server
|
|
533
|
+
- **certbot** - SSL certificates
|
|
534
|
+
- **git** - Source code management
|
|
535
|
+
- **nodejs** / **nvm** - For Node.js applications
|
|
536
|
+
- **python3-venv** - For Python applications
|
|
537
|
+
|
|
538
|
+
WASM will check and prompt for missing dependencies during installation.
|
|
539
|
+
|
|
540
|
+
---
|
|
541
|
+
|
|
542
|
+
## 🤝 Contributing
|
|
543
|
+
|
|
544
|
+
We welcome contributions! Please see our [Contributing Guide](.github/CONTRIBUTING.md) for details.
|
|
545
|
+
|
|
546
|
+
```bash
|
|
547
|
+
# Development setup
|
|
548
|
+
git clone https://github.com/Perkybeet/wasm.git
|
|
549
|
+
cd wasm
|
|
550
|
+
python -m venv venv
|
|
551
|
+
source venv/bin/activate
|
|
552
|
+
pip install -e ".[dev]"
|
|
553
|
+
|
|
554
|
+
# Run tests
|
|
555
|
+
pytest
|
|
556
|
+
|
|
557
|
+
# Build and upload to OBS (all distributions)
|
|
558
|
+
make obs-upload
|
|
559
|
+
|
|
560
|
+
# Check OBS build status
|
|
561
|
+
make obs-status
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
For detailed information about building and uploading to OBS, see [docs/OBS_SETUP.md](docs/OBS_SETUP.md).
|
|
565
|
+
|
|
566
|
+
---
|
|
567
|
+
|
|
568
|
+
## 📜 License
|
|
569
|
+
|
|
570
|
+
**WASM-NCSAL 1.0** - Free for personal and educational use.
|
|
571
|
+
For commercial use or business environments, a commercial license is required.
|
|
572
|
+
|
|
573
|
+
This project is licensed under the **WASM Non-Commercial Source-Available License (WASM-NCSAL) Version 1.0**.
|
|
574
|
+
|
|
575
|
+
### ✅ You CAN (Free):
|
|
576
|
+
- Use for **personal projects** and **learning**
|
|
577
|
+
- Study, modify, and adapt the code
|
|
578
|
+
- Contribute improvements to the project
|
|
579
|
+
- Distribute copies (maintaining the license)
|
|
580
|
+
|
|
581
|
+
### ❌ You CANNOT (Requires License):
|
|
582
|
+
- Use in **commercial environments** (companies, startups, agencies)
|
|
583
|
+
- Use to **reduce business costs** or gain competitive advantages
|
|
584
|
+
- Sell or monetize the software or derivatives
|
|
585
|
+
- Provide paid services using this software
|
|
586
|
+
|
|
587
|
+
### 💼 Need a Commercial License?
|
|
588
|
+
|
|
589
|
+
If you're a business or want to use WASM commercially:
|
|
590
|
+
|
|
591
|
+
- 📧 **Email:** yago.lopez.adeje@gmail.com | hello@bitbeet.dev
|
|
592
|
+
- 📱 **Phone:** +34 637 881 066
|
|
593
|
+
- 🌐 **Web:** [bitbeet.dev](https://bitbeet.dev)
|
|
594
|
+
|
|
595
|
+
👉 **[Read full license terms](LICENSE)**
|
|
596
|
+
|
|
597
|
+
---
|
|
598
|
+
|
|
599
|
+
## 🙏 Acknowledgments
|
|
600
|
+
|
|
601
|
+
- [Certbot](https://certbot.eff.org/) for SSL automation
|
|
602
|
+
- [python-inquirer](https://github.com/magmax/python-inquirer) for interactive CLI
|
|
603
|
+
- The open-source community
|
|
604
|
+
|
|
605
|
+
---
|
|
606
|
+
|
|
607
|
+
<p align="center">
|
|
608
|
+
Made with ❤️ by <a href="https://bitbeet.dev">Bitbeet</a>
|
|
609
|
+
</p>
|