mirror of
https://github.com/HeyPuter/puter
synced 2024-11-14 14:03:42 +00:00
Merge branch 'HeyPuter:main' into main
This commit is contained in:
commit
3acabc6c79
@ -57,25 +57,44 @@ See [doc/contributors/index.md](./doc/contributors/index.md) for more informatio
|
||||
|
||||
<br>
|
||||
|
||||
## PR Standards
|
||||
|
||||
We expect the following from pull requests (it makes things easier):
|
||||
- If you're closing an issue, please reference that issue in the PR description
|
||||
- Avoid whitespace changes
|
||||
- No regressions for "appspace" (Puter apps)
|
||||
|
||||
<br>
|
||||
|
||||
## Commit Messages
|
||||
|
||||
Use the imperative, as is the convention in the Linux kernel:
|
||||
**Note:** we will squash-merge some PRs so they follow . Large PRs should follow conventional commits also. The instructions below are outdated but suitable for most PRs.
|
||||
|
||||
- correct: `Improve performance of readdir`
|
||||
- incorrect: `Improved readdir`
|
||||
- incorrect: `Improving readdir`
|
||||
### Conventional Commits
|
||||
We use [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) with the following prefixes:
|
||||
- `fix:` for bug fixes
|
||||
- `dev:` instead of `refactor:`; covers more basis
|
||||
- `tweak:` for small updates
|
||||
- `sync:` when updating data from another source
|
||||
- `feat:` for a commit that first introduces a new feature
|
||||
|
||||
Commit messages after the prefix should use the imperative (the same convention used in the repo for Linux, which Git was built for):
|
||||
|
||||
- correct: `dev: improve performance of readdir`
|
||||
- incorrect: `dev: improved readdir`
|
||||
- incorrect: `dev: improving readdir`
|
||||
|
||||
We have the following exceptions to this rule:
|
||||
- If the commit message is in _past tense_, it's a shorthand for the following:
|
||||
- `Apply changes that would be applied after one had <past tense message>`
|
||||
- `dev: apply changes that would be applied after one had <past tense message>`
|
||||
- If the commit message is in _present tense_, it's shorthand for the following:
|
||||
- `Apply changes that would be applied after <present-tense message>`
|
||||
- `dev: apply changes that would be applied after <present-tense message>`
|
||||
|
||||
For example, the following are correct:
|
||||
- `Improved readdir`
|
||||
- interpret this as: `Apply changes that would be applied after one had improved readdir`
|
||||
- `Improving readdir`
|
||||
- interpret this as: `Apply changes that would be applied after improving readdir`
|
||||
- `dev: improved readdir`
|
||||
- interpret this as: `dev: apply changes that would be applied after one had improved readdir`
|
||||
- `dev: improving readdir`
|
||||
- interpret this as: `dev: apply changes that would be applied after improving readdir`
|
||||
|
||||
<br>
|
||||
|
||||
|
@ -132,18 +132,25 @@ This repository, including all its contents, sub-projects, modules, and componen
|
||||
|
||||
## Translations
|
||||
|
||||
- [Arabic / العربية](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ar.md)
|
||||
- [Bengali / বাংলা](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.bn.md)
|
||||
- [Chinese / 中文](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.zh.md)
|
||||
- [Danish / Dansk](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.da.md)
|
||||
- [English](https://github.com/HeyPuter/puter/blob/main/README.md)
|
||||
- [French / Français](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.da.md)
|
||||
- [Finnish / Suomi](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.fi.md)
|
||||
- [French / Français](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.fr.md)
|
||||
- [Hindi / हिंदी](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.hi.md)
|
||||
- [Indonesian / Bahasa Indonesia](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.id.md)
|
||||
- [Italian / Italiano](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.it.md)
|
||||
- [Japanese / 日本語](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.jp.md)
|
||||
- [Korean / 한국어](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ko.md)
|
||||
- [Polish / Polski](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.pl.md)
|
||||
- [Portuguese / Português](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.pt.md)
|
||||
- [Romanian / Română](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ro.md)
|
||||
- [Russian / Русский](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ru.md)
|
||||
- [Spanish / Español](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.es.md)
|
||||
- [Tamil / தமிழ்](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ta.md)
|
||||
- [Thai / ไทย](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.th.md)
|
||||
- [Turkish / Türkçe](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.tr.md)
|
||||
- [Urdu / اردو](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.ur.md)
|
||||
- [Vietnamese / Tiếng Việt](https://github.com/HeyPuter/puter/blob/main/doc/i18n/README.vi.md)
|
||||
|
133
doc/i18n/README.ar.md
Normal file
133
doc/i18n/README.ar.md
Normal file
@ -0,0 +1,133 @@
|
||||
<h3 align="center"><img width="80" alt="Puter.com، الحاسوب السحابي الشخصي: جميع ملفاتك وتطبيقاتك وألعابك في مكان واحد يمكن الوصول إليه من أي مكان في أي وقت." src="https://assets.puter.site/puter-logo.png"></h3>
|
||||
|
||||
<h3 align="center">نظام تشغيل الإنترنت! مجاني ومفتوح المصدر وقابل للاستضافة الذاتية.</h3>
|
||||
|
||||
<p align="center">
|
||||
<img alt="GitHub repo size" src="https://img.shields.io/github/repo-size/HeyPuter/puter"> <img alt="GitHub Release" src="https://img.shields.io/github/v/release/HeyPuter/puter?label=latest%20version"> <img alt="GitHub License" src="https://img.shields.io/github/license/HeyPuter/puter">
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://puter.com/"><strong>« عرض توضيحي مباشر »</strong></a>
|
||||
<br />
|
||||
<br />
|
||||
<a href="https://puter.com">Puter.com</a>
|
||||
·
|
||||
<a href="https://docs.puter.com" target="_blank">مجموعة أدوات التطوير</a>
|
||||
·
|
||||
<a href="https://discord.com/invite/PQcx7Teh8u">ديسكورد</a>
|
||||
·
|
||||
<a href="https://www.youtube.com/@EricsPuterVideos">يوتيوب</a>
|
||||
·
|
||||
<a href="https://reddit.com/r/puter">ريديت</a>
|
||||
·
|
||||
<a href="https://twitter.com/HeyPuter">إكس (تويتر)</a>
|
||||
·
|
||||
<a href="https://hackerone.com/puter_h1b">مكافأة اكتشاف الثغرات</a>
|
||||
</p>
|
||||
|
||||
<h3 align="center"><img width="800" style="border-radius:5px;" alt="لقطة شاشة" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
|
||||
|
||||
<br/>
|
||||
|
||||
## بيوتر
|
||||
|
||||
<div dir="rtl">
|
||||
<p>بيوتر هو نظام تشغيل إنترنت متقدم ومفتوح المصدر، مصمم ليكون غنيًا بالميزات وسريعًا بشكل استثنائي وقابلًا للتوسع بدرجة كبيرة. يمكن استخدام بيوتر كـ:</p>
|
||||
|
||||
<ul>
|
||||
<li>سحابة شخصية تعطي الأولوية للخصوصية لحفظ جميع ملفاتك وتطبيقاتك وألعابك في مكان آمن واحد، يمكن الوصول إليه من أي مكان وفي أي وقت.</li>
|
||||
<li>منصة لبناء ونشر المواقع الإلكترونية وتطبيقات الويب والألعاب</li>
|
||||
<li>بديل لـ Dropbox وGoogle Drive وOneDrive وغيرها، مع واجهة جديدة وميزات قوية.</li>
|
||||
<li>بيئة سطح مكتب عن بُعد للخوادم ومحطات العمل.</li>
|
||||
<li>مشروع ومجتمع ودود ومفتوح المصدر للتعلم عن تطوير الويب والحوسبة السحابية والأنظمة الموزعة والكثير غير ذلك!</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<br/>
|
||||
|
||||
## البدء
|
||||
|
||||
### 💻 التطوير المحلي
|
||||
|
||||
```bash
|
||||
git clone https://github.com/HeyPuter/puter
|
||||
cd puter
|
||||
npm install
|
||||
npm start
|
||||
```
|
||||
|
||||
سيؤدي هذا إلى تشغيل Puter على http://puter.localhost:4100 (أو المنفذ التالي المتاح).
|
||||
|
||||
<br/>
|
||||
|
||||
### 🐳 دوكر
|
||||
|
||||
```bash
|
||||
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
|
||||
```
|
||||
|
||||
<br/>
|
||||
|
||||
### 🐙 دوكر كومبوز
|
||||
|
||||
#### لينكس/ماك
|
||||
|
||||
```bash
|
||||
mkdir -p puter/config puter/data
|
||||
sudo chown -R 1000:1000 puter
|
||||
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
|
||||
docker compose up
|
||||
```
|
||||
|
||||
<br/>
|
||||
|
||||
#### ويندوز
|
||||
|
||||
```powershell
|
||||
mkdir -p puter
|
||||
cd puter
|
||||
New-Item -Path "puter\config" -ItemType Directory -Force
|
||||
New-Item -Path "puter\data" -ItemType Directory -Force
|
||||
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
|
||||
docker compose up
|
||||
```
|
||||
|
||||
<br/>
|
||||
|
||||
### ☁️ موقع Puter.com
|
||||
|
||||
متاح Puter كخدمة مستضافة على[**puter.com**](https://puter.com)الموقع
|
||||
|
||||
<br/>
|
||||
|
||||
## متطلبات النظام
|
||||
|
||||
- **Operating Systems:** لينكس، ماك، ويندوز
|
||||
- **RAM** ٢ جيجابايت كحد أدنى (يوصى بـ ٤ جيجابايت)
|
||||
- **Disk Space:** ١ جيجابايت مساحة حرة
|
||||
- **Node.js:** الإصدار ١٦+ (يوصى بالإصدار ٢٢+)
|
||||
- **npm:** أحدث إصدار مستقر
|
||||
|
||||
<br/>
|
||||
|
||||
## الدعم
|
||||
|
||||
تواصل مع المشرفين والمجتمع من خلال هذه القنوات:
|
||||
|
||||
- تقرير عن خطأ أو طلب ميزة؟ الرجاء [فتح مشكلة](https://github.com/HeyPuter/puter/issues/new/choose)
|
||||
|
||||
- دسكورد: [discord.com/invite/PQcx7Teh8u](https://discord.com/invite/PQcx7Teh8u)
|
||||
- إكس (تويتر): [x.com/HeyPuter](https://x.com/HeyPuter)
|
||||
- ريديت: [/reddit.com/r/puter](https://www.reddit.com/r/puter/)
|
||||
- ماستودون: [mastodon.social/@puter](https://mastodon.social/@puter)
|
||||
- مشاكل أمنية؟ [security@puter.com](mailto:security@puter.com)
|
||||
- البريد الإلكتروني للمشرفين [hi@puter.com](mailto:hi@puter.com)
|
||||
|
||||
نحن دائمًا سعداء لمساعدتك في أي أسئلة قد تكون لديك. لا تتردد في السؤال!
|
||||
|
||||
<br/>
|
||||
|
||||
## الترخيص
|
||||
|
||||
هذا المستودع، بما في ذلك جميع محتوياته ومشاريعه الفرعية ووحداته ومكوناته، مرخص تحت [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt) ما لم ينص على خلاف ذلك صراحةً. قد تخضع المكتبات الخارجية المدرجة في هذا المستودع لتراخيصها الخاصة.
|
||||
|
||||
<br/>
|
130
doc/i18n/README.fi.md
Normal file
130
doc/i18n/README.fi.md
Normal file
@ -0,0 +1,130 @@
|
||||
<h3 align="center"><img width="80" alt="Puter.com, The Personal Cloud Computer: All your files, apps, and games in one place accessible from anywhere at any time." src="https://assets.puter.site/puter-logo.png"></h3>
|
||||
<h3 align="center">Internetin käyttöjärjestelmä! Ilmainen, avoimen lähdekoodin ja itse isännöitävä.</h3>
|
||||
|
||||
<p align="center">
|
||||
<img alt="GitHub repo size" src="https://img.shields.io/github/repo-size/HeyPuter/puter"> <img alt="GitHub Release" src="https://img.shields.io/github/v/release/HeyPuter/puter?label=viimeisin%20versio"> <img alt="GitHub License" src="https://img.shields.io/github/license/HeyPuter/puter">
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://puter.com/"><strong>« LIVE DEMO »</strong></a>
|
||||
<br />
|
||||
<br />
|
||||
<a href="https://puter.com">Puter.com</a>
|
||||
·
|
||||
<a href="https://docs.puter.com" target="_blank">SDK</a>
|
||||
·
|
||||
<a href="https://discord.com/invite/PQcx7Teh8u">Discord</a>
|
||||
·
|
||||
<a href="https://www.youtube.com/@EricsPuterVideos">YouTube</a>
|
||||
·
|
||||
<a href="https://reddit.com/r/puter">Reddit</a>
|
||||
·
|
||||
<a href="https://twitter.com/HeyPuter">X (Twitter)</a>
|
||||
·
|
||||
<a href="https://hackerone.com/puter_h1b">Bug Bounty</a>
|
||||
</p>
|
||||
|
||||
<h3 align="center"><img width="800" style="border-radius:5px;" alt="näyttökuva" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
|
||||
|
||||
<br/>
|
||||
|
||||
## Puter
|
||||
|
||||
Puter on kehittynyt, avoimen lähdekoodin internetin käyttöjärjestelmä, joka on suunniteltu olemaan ominaisuuksiltaan rikas, poikkeuksellisen nopea ja erittäin laajennettava. Puteria voidaan käyttää:
|
||||
|
||||
- Yksityisyyttä kunnioittavana henkilökohtaisena pilvenä, johon voit tallentaa kaikki tiedostosi, sovelluksesi ja pelisi turvallisesti yhdessä paikassa, josta ne ovat saatavilla missä tahansa ja milloin tahansa.
|
||||
- Alustana verkkosivustojen, web-sovellusten ja pelien rakentamiseen ja julkaisemiseen.
|
||||
- Vaihtoehtona Dropboxille, Google Drivelle, OneDrivelle jne. tuoreella käyttöliittymällä ja tehokkailla ominaisuuksilla.
|
||||
- Etätyöpöytäympäristönä palvelimille ja työasemille.
|
||||
- Ystävällisenä, avoimen lähdekoodin projektina ja yhteisönä, jossa voit oppia verkkokehityksestä, pilvipalveluista, hajautetuista järjestelmistä ja paljon muusta!
|
||||
|
||||
<br/>
|
||||
|
||||
## Aloittaminen
|
||||
|
||||
|
||||
### 💻 Paikallinen kehitys
|
||||
|
||||
```bash
|
||||
git clone https://github.com/HeyPuter/puter
|
||||
cd puter
|
||||
npm install
|
||||
npm start
|
||||
```
|
||||
|
||||
Tämä käynnistää Puterin osoitteessa http://puter.localhost:4100 (tai seuraavassa vapaassa portissa).
|
||||
|
||||
<br/>
|
||||
|
||||
### 🐳 Docker
|
||||
|
||||
|
||||
```bash
|
||||
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
|
||||
```
|
||||
|
||||
<br/>
|
||||
|
||||
|
||||
### 🐙 Docker Compose
|
||||
|
||||
|
||||
#### Linux/macOS
|
||||
```bash
|
||||
mkdir -p puter/config puter/data
|
||||
sudo chown -R 1000:1000 puter
|
||||
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
|
||||
docker compose up
|
||||
```
|
||||
<br/>
|
||||
|
||||
#### Windows
|
||||
|
||||
|
||||
```powershell
|
||||
mkdir -p puter
|
||||
cd puter
|
||||
New-Item -Path "puter\config" -ItemType Directory -Force
|
||||
New-Item -Path "puter\data" -ItemType Directory -Force
|
||||
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
|
||||
docker compose up
|
||||
```
|
||||
<br/>
|
||||
|
||||
### ☁️ Puter.com
|
||||
|
||||
Puter on saatavilla isännöitynä palveluna osoitteessa [**puter.com**](https://puter.com).
|
||||
|
||||
<br/>
|
||||
|
||||
## Järjestelmävaatimukset
|
||||
|
||||
- **Käyttöjärjestelmät:** Linux, macOS, Windows
|
||||
- **RAM:** Vähintään 2GB (Suositeltu 4GB)
|
||||
- **Levytila:** 1GB vapaata tilaa
|
||||
- **Node.js:** Versio 16+ (Suositeltu versio 22+)
|
||||
- **npm:** Uusin vakaa versio
|
||||
|
||||
<br/>
|
||||
|
||||
## Tuki
|
||||
|
||||
Ota yhteyttä ylläpitäjiin ja yhteisöön näiden kanavien kautta:
|
||||
|
||||
- Onko sinulla virheraportti tai ominaisuuspyyntö? Ole hyvä ja [avaa uusi issue](https://github.com/HeyPuter/puter/issues/new/choose).
|
||||
- Discord: [discord.com/invite/PQcx7Teh8u](https://discord.com/invite/PQcx7Teh8u)
|
||||
- X (Twitter): [x.com/HeyPuter](https://x.com/HeyPuter)
|
||||
- Reddit: [reddit.com/r/puter/](https://www.reddit.com/r/puter/)
|
||||
- Mastodon: [mastodon.social/@puter](https://mastodon.social/@puter)
|
||||
- Turvallisuusongelmat? [security@puter.com](mailto:security@puter.com)
|
||||
- Ota yhteyttä ylläpitäjiin sähköpostitse osoitteessa [hi@puter.com](mailto:hi@puter.com)
|
||||
|
||||
Olemme aina valmiita auttamaan sinua kaikissa kysymyksissäsi. Älä epäröi kysyä!
|
||||
|
||||
<br/>
|
||||
|
||||
|
||||
## Lisenssi
|
||||
|
||||
Tämä repository, mukaan lukien kaikki sen sisältö, aliprojektit, moduulit ja komponentit, on lisensoitu [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt)-lisenssillä, ellei toisin mainita. Tämän repositoryn mukana tulevat kolmannen osapuolen kirjastot voivat olla omien lisenssiensä alaisia.
|
||||
|
||||
<br/>
|
123
doc/i18n/README.pl.md
Normal file
123
doc/i18n/README.pl.md
Normal file
@ -0,0 +1,123 @@
|
||||
<h3 align="center"><img width="80" alt="Puter.com, Osobisty Komputer Chmurowy: Wszystkie twoje pliki, aplikacje i gry w jednym miejscu, dostępne z dowolnego miejsca o dowolnej porze." src="https://assets.puter.site/puter-logo.png"></h3>
|
||||
<h3 align="center">System Operacyjny Internetu! Darmowy, Open-Source i Możliwy do Samodzielnego Hostowania.</h3>
|
||||
<p align="center">
|
||||
<img alt="Rozmiar repozytorium GitHub" src="https://img.shields.io/github/repo-size/HeyPuter/puter"> <img alt="Wydanie GitHub" src="https://img.shields.io/github/v/release/HeyPuter/puter?label=latest%20version"> <img alt="Licencja GitHub" src="https://img.shields.io/github/license/HeyPuter/puter">
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://puter.com/"><strong>« DEMO NA ŻYWO »</strong></a>
|
||||
<br />
|
||||
<br />
|
||||
<a href="https://puter.com">Puter.com</a>
|
||||
·
|
||||
<a href="https://docs.puter.com" target="_blank">SDK</a>
|
||||
·
|
||||
<a href="https://discord.com/invite/PQcx7Teh8u">Discord</a>
|
||||
·
|
||||
<a href="https://www.youtube.com/@EricsPuterVideos">YouTube</a>
|
||||
·
|
||||
<a href="https://reddit.com/r/puter">Reddit</a>
|
||||
·
|
||||
<a href="https://twitter.com/HeyPuter">X (Twitter)</a>
|
||||
·
|
||||
<a href="https://hackerone.com/puter_h1b">Bug Bounty</a>
|
||||
</p>
|
||||
<h3 align="center"><img width="800" style="border-radius:5px;" alt="zrzut ekranu" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
|
||||
<br/>
|
||||
|
||||
## Puter
|
||||
|
||||
Puter to zaawansowany, open-source'owy system operacyjny internetowy, zaprojektowany tak, aby był bogaty w funkcje, wyjątkowo szybki i wysoce rozszerzalny. Puter może być używany jako:
|
||||
|
||||
- Prywatna chmura osobista do przechowywania wszystkich plików, aplikacji i gier w jednym bezpiecznym miejscu, dostępnym z dowolnego miejsca o dowolnej porze.
|
||||
- Platforma do budowania i publikowania stron internetowych, aplikacji webowych i gier.
|
||||
- Alternatywa dla Dropbox, Google Drive, OneDrive itp. ze świeżym interfejsem i potężnymi funkcjami.
|
||||
- Zdalne środowisko pulpitu dla serwerów i stacji roboczych.
|
||||
- Przyjazny, open-source'owy projekt i społeczność do nauki o tworzeniu stron internetowych, chmurze obliczeniowej, systemach rozproszonych i wielu innych!
|
||||
|
||||
<br/>
|
||||
|
||||
## Rozpoczęcie pracy
|
||||
## 💻 Rozwój lokalny
|
||||
|
||||
```bash
|
||||
git clone https://github.com/HeyPuter/puter
|
||||
cd puter
|
||||
npm install
|
||||
npm start
|
||||
```
|
||||
To uruchomi Puter na http://puter.localhost:4100 (lub na następnym dostępnym porcie).
|
||||
|
||||
<br/>
|
||||
|
||||
## 🐳 Docker
|
||||
|
||||
```bash
|
||||
Copy code
|
||||
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
|
||||
```
|
||||
<br/>
|
||||
|
||||
## 🐙 Docker Compose
|
||||
## Linux/macOS
|
||||
|
||||
```bash
|
||||
Copy code
|
||||
mkdir -p puter/config puter/data
|
||||
sudo chown -R 1000:1000 puter
|
||||
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
|
||||
docker compose up
|
||||
```
|
||||
<br/>
|
||||
|
||||
## Windows
|
||||
|
||||
```powershell
|
||||
mkdir -p puter
|
||||
cd puter
|
||||
New-Item -Path "puter\config" -ItemType Directory -Force
|
||||
New-Item -Path "puter\data" -ItemType Directory -Force
|
||||
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
|
||||
docker compose up
|
||||
```
|
||||
<br/>
|
||||
|
||||
## ☁️ Puter.com
|
||||
Puter jest dostępny jako usługa hostowana na [**puter.com**](https://puter.com).
|
||||
|
||||
<br/>
|
||||
|
||||
## Wymagania systemowe
|
||||
|
||||
- **Systemy operacyjne:** Linux, macOS, Windows
|
||||
- **RAM:** Minimum 2GB (zalecane 4GB)
|
||||
- **Przestrzeń dyskowa:** 1GB wolnego miejsca
|
||||
- **Node.js:** Wersja 16+ (zalecana wersja 22+)
|
||||
- **npm:** Najnowsza stabilna wersja
|
||||
|
||||
<br/>
|
||||
|
||||
## Wsparcie
|
||||
|
||||
Połącz się z opiekunami i społecznością przez te kanały:
|
||||
|
||||
- Raport o błędzie lub prośba o funkcję? Proszę otworzyć zgłoszenie.
|
||||
- Discord: discord.com/invite/PQcx7Teh8u
|
||||
- X (Twitter): x.com/HeyPuter
|
||||
- Reddit: reddit.com/r/puter/
|
||||
- Mastodon: mastodon.social/@puter
|
||||
- Problemy z bezpieczeństwem? security@puter.com
|
||||
- Email do opiekunów: hi@puter.com
|
||||
|
||||
Zawsze chętnie pomożemy Ci z wszelkimi pytaniami, jakie możesz mieć. Nie wahaj się pytać!
|
||||
<br/>
|
||||
|
||||
## Licencja
|
||||
|
||||
To repozytorium, w tym cała jego zawartość, podprojekty, moduły i komponenty, jest licencjonowane na podstawie [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt), chyba że wyraźnie zaznaczono inaczej. Biblioteki stron trzecich zawarte w tym repozytorium mogą podlegać własnym licencjom.
|
||||
|
||||
<br/>
|
||||
|
||||
|
||||
|
||||
|
||||
|
129
doc/i18n/README.ro.md
Normal file
129
doc/i18n/README.ro.md
Normal file
@ -0,0 +1,129 @@
|
||||
<h3 align="center"><img width="80" alt="Puter.com, Calculatorul Personal Cloud: Toate fișierele, aplicațiile și jocurile dumneavoastră într-un singur loc, accesibile de oriunde și oricând." src="https://assets.puter.site/puter-logo.png"></h3>
|
||||
|
||||
<h3 align="center">Sistemul de Operare Internet! Gratuit, Open-Source și Găzduibil Autonom.</h3>
|
||||
|
||||
<p align="center">
|
||||
<img alt="Mărime GitHub repository" src="https://img.shields.io/github/repo-size/HeyPuter/puter"> <img alt="Versiune GitHub" src="https://img.shields.io/github/v/release/HeyPuter/puter?label=ultima%20versiune"> <img alt="Licență GitHub" src="https://img.shields.io/github/license/HeyPuter/puter">
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://puter.com/"><strong>« DEMO LIVE »</strong></a>
|
||||
<br />
|
||||
<br />
|
||||
<a href="https://puter.com">Puter.com</a>
|
||||
·
|
||||
<a href="https://docs.puter.com" target="_blank">SDK</a>
|
||||
·
|
||||
<a href="https://discord.com/invite/PQcx7Teh8u">Discord</a>
|
||||
·
|
||||
<a href="https://www.youtube.com/@EricsPuterVideos">YouTube</a>
|
||||
·
|
||||
<a href="https://reddit.com/r/puter">Reddit</a>
|
||||
·
|
||||
<a href="https://twitter.com/HeyPuter">X (Twitter)</a>
|
||||
·
|
||||
<a href="https://hackerone.com/puter_h1b">Bug Bounty</a>
|
||||
</p>
|
||||
|
||||
<h3 align="center"><img width="800" style="border-radius:5px;" alt="screenshot" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
|
||||
|
||||
<br/>
|
||||
|
||||
## Puter
|
||||
|
||||
Puter este un sistem de operare pe internet avansat, open-source, proiectat să fie bogat în funcții, extrem de rapid și foarte extensibil. Puter poate fi folosit ca:
|
||||
|
||||
- Un cloud personal care pune pe primul loc confidențialitatea pentru a păstra toate fișierele, aplicațiile și jocurile tale într-un loc sigur, accesibil de oriunde și oricând.
|
||||
- O platforma pentru a construi și publica site-uri web, aplicații web și jocuri.
|
||||
- O alternativă la Dropbox, Google Drive, OneDrive, etc. cu o interfață nouă și funcționalități puternice.
|
||||
- Un mediu desktop la distanță pentru servere si stații de lucru.
|
||||
- Un proiect prietenos, open-source și o comunitate pentru a învăța despre dezvoltarea web, cloud computing, sisteme distribuite și multe altele!
|
||||
|
||||
<br/>
|
||||
|
||||
## Începeți
|
||||
|
||||
### 💻 Dezvoltare Locală
|
||||
|
||||
```bash
|
||||
git clone https://github.com/HeyPuter/puter
|
||||
cd puter
|
||||
npm install
|
||||
npm start
|
||||
```
|
||||
|
||||
Aceasta va lansa Puter la adresa http://puter.localhost:4100 (sau la următorul port disponibil).
|
||||
|
||||
<br/>
|
||||
|
||||
### 🐳 Docker
|
||||
|
||||
|
||||
```bash
|
||||
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
|
||||
```
|
||||
|
||||
<br/>
|
||||
|
||||
|
||||
### 🐙 Docker Compose
|
||||
|
||||
|
||||
#### Linux/macOS
|
||||
```bash
|
||||
mkdir -p puter/config puter/data
|
||||
sudo chown -R 1000:1000 puter
|
||||
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
|
||||
docker compose up
|
||||
```
|
||||
<br/>
|
||||
|
||||
#### Windows
|
||||
|
||||
|
||||
```powershell
|
||||
mkdir -p puter
|
||||
cd puter
|
||||
New-Item -Path "puter\config" -ItemType Directory -Force
|
||||
New-Item -Path "puter\data" -ItemType Directory -Force
|
||||
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
|
||||
docker compose up
|
||||
```
|
||||
<br/>
|
||||
|
||||
### ☁️ Puter.com
|
||||
|
||||
Puter este disponibil ca serviciu găzduit la [**puter.com**](https://puter.com).
|
||||
|
||||
<br/>
|
||||
|
||||
## Cerințe de Sistem
|
||||
|
||||
- **Sisteme de Operare:** Linux, macOS, Windows
|
||||
- **RAM:** 2GB minim (4GB recomandat)
|
||||
- **Spațiu pe Disk:** 1GB spațiu liber
|
||||
- **Node.js:** Versiunea 16+ (Versiunea 22+ recomandată)
|
||||
- **npm:** Ultima versiune stabilă
|
||||
|
||||
<br/>
|
||||
|
||||
## Suport
|
||||
|
||||
Conectați-vă cu cei care asigură mentenanța proiectului și comunitatea prin intermediul acestor canale:
|
||||
|
||||
- Aveți o problemă sau doriți o funcționalitate nouă? Vă rugăm [să deschideți o problemă](https://github.com/HeyPuter/puter/issues/new/choose).
|
||||
- Discord: [discord.com/invite/PQcx7Teh8u](https://discord.com/invite/PQcx7Teh8u)
|
||||
- X (Twitter): [x.com/HeyPuter](https://x.com/HeyPuter)
|
||||
- Reddit: [reddit.com/r/puter/](https://www.reddit.com/r/puter/)
|
||||
- Mastodon: [mastodon.social/@puter](https://mastodon.social/@puter)
|
||||
- Probleme de securitate? [security@puter.com](mailto:security@puter.com)
|
||||
- Trimiteți un email celor care asigură mentenanța proiectul la [hi@puter.com](mailto:hi@puter.com)
|
||||
|
||||
Suntem întotdeauna bucuroși să vă ajutăm cu orice întrebări aveți. Nu ezitați să ne întrebați!
|
||||
|
||||
<br/>
|
||||
|
||||
## Licență
|
||||
|
||||
Acest depozit, inclusiv toate conținuturile sale, sub-proiectele, modulele și componentele, sunt licențiate sub [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt), cu excepția cazului în care se menționează altfel în mod explicit. Bibliotecile terțe incluse în acest depozit pot fi supuse propriilor licențe.
|
||||
|
||||
<br/>
|
131
doc/i18n/README.th.md
Normal file
131
doc/i18n/README.th.md
Normal file
@ -0,0 +1,131 @@
|
||||
<h3 align="center"><img width="80" alt="Puter.com, The Personal Cloud Computer: All your files, apps, and games in one place accessible from anywhere at any time." src="https://assets.puter.site/puter-logo.png"></h3>
|
||||
|
||||
<h3 align="center">ระบบปฏิบัติการอินเทอร์เน็ต ฟรี, โอเพ่นซอร์ส, และสามารถโฮสต์ได้ด้วยตนเอง</h3>
|
||||
|
||||
<p align="center">
|
||||
<img alt="GitHub repo size" src="https://img.shields.io/github/repo-size/HeyPuter/puter"> <img alt="GitHub Release" src="https://img.shields.io/github/v/release/HeyPuter/puter?label=latest%20version"> <img alt="GitHub License" src="https://img.shields.io/github/license/HeyPuter/puter">
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://puter.com/"><strong>« การสาธิตสด »</strong></a>
|
||||
<br />
|
||||
<br />
|
||||
<a href="https://puter.com">Puter.com</a>
|
||||
·
|
||||
<a href="https://docs.puter.com" target="_blank">ชุดพัฒนาโปรแกรม</a>
|
||||
·
|
||||
<a href="https://discord.com/invite/PQcx7Teh8u">ดิสคอร์ด</a>
|
||||
·
|
||||
<a href="https://www.youtube.com/@EricsPuterVideos">ยูทูบ</a>
|
||||
·
|
||||
<a href="https://reddit.com/r/puter">เรดดิท</a>
|
||||
·
|
||||
<a href="https://twitter.com/HeyPuter">X (ทวิตเตอร์)</a>
|
||||
·
|
||||
<a href="https://hackerone.com/puter_h1b">นักล่าบั๊ก</a>
|
||||
</p>
|
||||
|
||||
<h3 align="center"><img width="800" style="border-radius:5px;" alt="screenshot" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
|
||||
|
||||
<br/>
|
||||
|
||||
## พิวเตอร์
|
||||
|
||||
พิวเตอร์ เป็นระบบปฏิบัติการอินเทอร์เน็ตขั้นสูงแบบโอเพ่นซอร์สที่ออกแบบมาให้มีฟีเจอร์ครบถ้วน ความเร็วสูง และมีความสามารถที่จะขยายได้สูง. พิวเตอร์ สามารถใช้ได้เป็น:
|
||||
|
||||
- คลาวด์ส่วนตัว เพื่อเก็บไฟล์, แอพพลิเคชัน, และเกมทั้งหมดของคุณในที่เดียวที่ปลอดภัยและสามารถเข้าถึงได้ทุกที่ทุกเวลา
|
||||
- แพลตฟอร์มสำหรับการสร้างและเผยแพร่เว็บไซต์, เว็บแอปพลิเคชัน, และเกม
|
||||
- ทางเลือกอีกหนึ่งทางที่สามารถใช้แทน Dropbox, Google Drive, OneDrive ฯลฯ โดยที่มีอินเทอร์เฟซใหม่และฟีเจอร์ที่ทรงพลัง
|
||||
- สภาพแวดล้อมสำหรับเดสก์ท็อประยะไกลที่ใช้กับเซิร์ฟเวอร์และสถานีทำงาน
|
||||
- โครงการโอเพ่นซอร์สและชุมชนที่เป็นมิตรที่คุณสามารถเรียนรู้เกี่ยวกับการพัฒนาเว็บ, คลาวด์คอมพิวติ้ง, ระบบกระจาย, และอีกมากมาย
|
||||
|
||||
<br/>
|
||||
|
||||
## การเริ่มต้นใช้งาน
|
||||
|
||||
|
||||
### 💻 การพัฒนาภายในเครื่อง
|
||||
|
||||
```bash
|
||||
git clone https://github.com/HeyPuter/puter
|
||||
cd puter
|
||||
npm install
|
||||
npm start
|
||||
```
|
||||
|
||||
พิวเตอร์ จะถูกเปิดใช้งานที่ http://puter.localhost:4100 (หรือพอร์ตถัดไปที่ว่าง).
|
||||
|
||||
<br/>
|
||||
|
||||
### 🐳 ด็อกเกอร์
|
||||
|
||||
|
||||
```bash
|
||||
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
|
||||
```
|
||||
|
||||
<br/>
|
||||
|
||||
|
||||
### 🐙 ด็อกเกอร์ คอมโพส
|
||||
|
||||
|
||||
#### ลินุกซ์/แมคโอเอส
|
||||
```bash
|
||||
mkdir -p puter/config puter/data
|
||||
sudo chown -R 1000:1000 puter
|
||||
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
|
||||
docker compose up
|
||||
```
|
||||
<br/>
|
||||
|
||||
#### วินโดวส์
|
||||
|
||||
|
||||
```powershell
|
||||
mkdir -p puter
|
||||
cd puter
|
||||
New-Item -Path "puter\config" -ItemType Directory -Force
|
||||
New-Item -Path "puter\data" -ItemType Directory -Force
|
||||
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
|
||||
docker compose up
|
||||
```
|
||||
<br/>
|
||||
|
||||
### ☁️ Puter.com
|
||||
|
||||
สามารถใช้งาน พิวเตอร์ ได้ในรูปแบบบริการโฮสต์ที่ [**puter.com**](https://puter.com).
|
||||
|
||||
<br/>
|
||||
|
||||
## ข้อกำหนดของระบบ
|
||||
|
||||
- **ระบบปฏิบัติการ:** ลินุกซ์ แมคโอเอส วินโดวส์
|
||||
- **แรม:** อย่างน้อย 2GB (แนะนำ 4GB)
|
||||
- **พื้นที่เก็บข้อมูล:** พื้นที่ว่าง 1GB
|
||||
- **Node.js:** เวอร์ชัน 16+ (แนะนำเวอร์ชัน 22+)
|
||||
- **npm:** เวอร์ชันล่าสุดที่เสถียร
|
||||
|
||||
<br/>
|
||||
|
||||
## การช่วยเหลือ
|
||||
|
||||
ติดต่อกับผู้ดูแลระบบและชุมชนผ่านช่องทางเหล่านี้:
|
||||
|
||||
- พบข้อผิดพลาดหรือขอฟีเจอร์ใหม่? กรุณา [เปิดปัญหา](https://github.com/HeyPuter/puter/issues/new/choose).
|
||||
- ดิสคอร์ด: [discord.com/invite/PQcx7Teh8u](https://discord.com/invite/PQcx7Teh8u)
|
||||
- X (ทวิตเตอร์): [x.com/HeyPuter](https://x.com/HeyPuter)
|
||||
- เรดดิท: [reddit.com/r/puter/](https://www.reddit.com/r/puter/)
|
||||
- มาสตอดอน: [mastodon.social/@puter](https://mastodon.social/@puter)
|
||||
- ปัญหาด้านความปลอดภัย [security@puter.com](mailto:security@puter.com)
|
||||
- ส่งอีเมลถึงผู้ดูแลระบบได้ที่ [hi@puter.com](mailto:hi@puter.com)
|
||||
|
||||
เรายินดีเสมอที่จะช่วยเหลือคุณกับทุกทุกคำถามที่คุณมี อย่าลังเลที่จะถาม
|
||||
|
||||
<br/>
|
||||
|
||||
|
||||
## ลิขสิทธิ์
|
||||
|
||||
ที่เก็บข้อมูลนี้ รวมถึงเนื้อหาทั้งหมด, โครงการย่อย, โมดูล, และส่วนประกอบต่างๆ ได้รับใบอนุญาตภายใต้ [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt) เว้นแต่จะมีการระบุไว้เป็นอย่างอื่นอย่างชัดเจน ไลบรารีจากบุคคลที่สามที่รวมอยู่ในที่เก็บข้อมูลนี้อาจอยู่ภายใต้ใบอนุญาตของตนเอง
|
||||
|
||||
<br/>
|
125
doc/i18n/README.ur.md
Normal file
125
doc/i18n/README.ur.md
Normal file
@ -0,0 +1,125 @@
|
||||
<h3 align="center"><img width="80" alt="Puter.com, ذاتی کلاؤڈ کمپیوٹر: آپ کی تمام فائلیں، ایپس، اور کھیل ایک جگہ پر، کہیں سے بھی اور کسی بھی وقت قابل رسائی۔" src="https://assets.puter.site/puter-logo.png"></h3>
|
||||
|
||||
<h3 align="center">انٹرنیٹ OS! مفت، اوپن سورس، اور خود میزبان.</h3>
|
||||
|
||||
<p align="center">
|
||||
<img alt="GitHub repo size" src="https://img.shields.io/github/repo-size/HeyPuter/puter"> <img alt="GitHub Release" src="https://img.shields.io/github/v/release/HeyPuter/puter?label=latest%20version"> <img alt="GitHub License" src="https://img.shields.io/github/license/HeyPuter/puter">
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://puter.com/"><strong>« لائیو ڈیمو »</strong></a>
|
||||
<br />
|
||||
<br />
|
||||
<a href="https://puter.com">Puter.com</a>
|
||||
·
|
||||
<a href="https://docs.puter.com" target="_blank">SDK</a>
|
||||
·
|
||||
<a href="https://discord.com/invite/PQcx7Teh8u">ڈسکورڈ</a>
|
||||
·
|
||||
<a href="https://www.youtube.com/@EricsPuterVideos">یوٹیوب</a>
|
||||
·
|
||||
<a href="https://reddit.com/r/puter">ریڈڈٹ</a>
|
||||
·
|
||||
<a href="https://twitter.com/HeyPuter">ایکس (ٹوئٹر)</a>
|
||||
·
|
||||
<a href="https://hackerone.com/puter_h1b">بگ باؤنٹی</a>
|
||||
</p>
|
||||
|
||||
<h3 align="center"><img width="800" style="border-radius:5px;" alt="اسکرین شاٹ" src="https://assets.puter.site/puter.com-screenshot-3.webp"></h3>
|
||||
|
||||
<br/>
|
||||
|
||||
## Puter
|
||||
|
||||
ایک جدید، اوپن سورس انٹرنیٹ آپریٹنگ سسٹم ہے جو کہ خصوصیات سے بھرپور، بہت تیز، اور انتہائی توسیع پذیر ہے۔ Puter
|
||||
|
||||
: کو استعمال کیا جا سکتا ہے Puter
|
||||
|
||||
- ایک پرائیویسی فرسٹ ذاتی کلاؤڈ کے طور پر تاکہ آپ کی تمام فائلیں، ایپس، اور کھیل ایک محفوظ جگہ پر رکھی جا سکیں، کہیں سے بھی اور کسی بھی وقت قابل رسائی ہوں۔
|
||||
- ویب سائٹس، ویب ایپس، اور کھیل بنانے اور شائع کرنے کے لئے ایک پلیٹ فارم کے طور پر۔
|
||||
- وغیرہ کا متبادل، نئے انٹرفیس اور طاقتور خصوصیات کے ساتھ۔ Dropbox، Google Drive، OneDrive
|
||||
- سرورز اور ورک اسٹیشنز کے لیے ایک ریموٹ ڈیسک ٹاپ ماحول کے طور پر۔
|
||||
- ویب ڈویلپمنٹ، کلاؤڈ کمپیوٹنگ، تقسیم شدہ نظاموں، اور بہت کچھ سیکھنے کے لیے ایک دوستانہ، اوپن سورس پروجیکٹ اور کمیونٹی!
|
||||
|
||||
<br/>
|
||||
|
||||
## شروع کرنے کا طریقہ
|
||||
|
||||
### 💻 مقامی ترقی
|
||||
|
||||
```bash
|
||||
git clone https://github.com/HeyPuter/puter
|
||||
cd puter
|
||||
npm install
|
||||
npm start
|
||||
```
|
||||
|
||||
یہ Puter کو http://puter.localhost:4100 (یا اگلے دستیاب پورٹ) پر لانچ کرے گا۔
|
||||
|
||||
<br/>
|
||||
🐳 Docker
|
||||
|
||||
```bash
|
||||
mkdir puter && cd puter && mkdir -p puter/config puter/data && sudo chown -R 1000:1000 puter && docker run --rm -p 4100:4100 -v `pwd`/puter/config:/etc/puter -v `pwd`/puter/data:/var/puter ghcr.io/heyputer/puter
|
||||
```
|
||||
|
||||
<br/>
|
||||
🐙 Docker Compose
|
||||
Linux/macOS
|
||||
|
||||
```bash
|
||||
mkdir -p puter/config puter/data
|
||||
sudo chown -R 1000:1000 puter
|
||||
wget https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml
|
||||
docker compose up
|
||||
```
|
||||
|
||||
<br/>
|
||||
Windows
|
||||
|
||||
```powershell
|
||||
mkdir -p puter
|
||||
cd puter
|
||||
New-Item -Path "puter\config" -ItemType Directory -Force
|
||||
New-Item -Path "puter\data" -ItemType Directory -Force
|
||||
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/HeyPuter/puter/main/docker-compose.yml" -OutFile "docker-compose.yml"
|
||||
docker compose up
|
||||
```
|
||||
<br/>
|
||||
|
||||
### ☁️ Puter.com
|
||||
|
||||
Puter کو [**puter.com**](https://puter.com) پر میزبان سروس کے طور پر دستیاب ہے۔
|
||||
|
||||
<br/>
|
||||
|
||||
## نظام کی ضروریات
|
||||
|
||||
- **آپریٹنگ سسٹمز:** لینکس، macOS، ونڈوز
|
||||
- **RAM:** کم از کم 2GB (4GB تجویز کردہ)
|
||||
- **ڈسک کی جگہ:** 1GB خالی جگہ
|
||||
- **Node.js:** ورژن 16+ (ورژن 22+ تجویز کردہ)
|
||||
- **npm:** تازہ ترین مستحکم ورژن
|
||||
|
||||
<br/>
|
||||
|
||||
## سپورٹ
|
||||
|
||||
منتظمین اور کمیونٹی سے جڑنے کے لیے یہ چینلز استعمال کریں:
|
||||
|
||||
- بگ رپورٹ یا فیچر درخواست؟ براہ کرم [ایک مسئلہ کھولیں](https://github.com/HeyPuter/puter/issues/new/choose).
|
||||
- ڈسکورڈ: [discord.com/invite/PQcx7Teh8u](https://discord.com/invite/PQcx7Teh8u)
|
||||
- ایکس (ٹوئٹر): [x.com/HeyPuter](https://x.com/HeyPuter)
|
||||
- ریڈڈٹ: [reddit.com/r/puter/](https://www.reddit.com/r/puter/)
|
||||
- ماسٹڈون: [mastodon.social/@puter](https://mastodon.social/@puter)
|
||||
- سیکیورٹی کے مسائل؟ [security@puter.com](mailto:security@puter.com)
|
||||
- منتظمین کو ای میل کریں [hi@puter.com](mailto:hi@puter.com)
|
||||
|
||||
ہم ہمیشہ آپ کی مدد کے لیے خوش ہیں۔ سوالات پوچھنے میں ہچکچاہٹ نہ کریں
|
||||
!
|
||||
<br/>
|
||||
|
||||
## لائسنس
|
||||
|
||||
اس ریپوزٹری، بشمول اس کے تمام مواد، ذیلی پروجیکٹس، ماڈیولز، اور کمپوننٹس، کو [AGPL-3.0](https://github.com/HeyPuter/puter/blob/main/LICENSE.txt) کے تحت لائسنس کیا گیا ہے جب تک کہ واضح طور پر کہیں اور نہ کہا گیا ہو۔ اس ریپوزٹری میں شامل تھرڈ پارٹی لائبریریاں اپنی لائسنس کے تابع ہو سکتی ہیں۔
|
||||
|
||||
<br/>
|
@ -5,16 +5,12 @@
|
||||
|
||||
### Self-Hosting Differences
|
||||
Currently, the self-hosted version of Puter is different in a few ways from [Puter.com](https://puter.com):
|
||||
- There is no built-in way to install or create other apps (see below)
|
||||
- Several "core" apps are missing, such as **Code** or **Draw**, because we can't include them in this repository
|
||||
- Some icons are different
|
||||
- There is no built-in way to access apps from puter.com (see below)
|
||||
- Several "core" apps are missing, such as **Code** or **Draw**
|
||||
- Some assets are different
|
||||
|
||||
Work is ongoing to improve the **App Center** and make it available on self-hosted.
|
||||
Until then, it's possible to add other apps by manually editing the database file.
|
||||
This process is not recommended unless you know what you are doing.
|
||||
The file will appear after you first launch Puter, and should be found in `puter/data/puter-database.sqlite` for Docker,
|
||||
or `volatile/runtime/puter-database.sqlite` otherwise.
|
||||
You will need a database tool that can understand SQLite databases.
|
||||
Until then, it is still possible to add apps using the **Dev Center** app.
|
||||
|
||||
<br/>
|
||||
|
||||
@ -55,4 +51,4 @@ A warning will persist in the dev console until this user's
|
||||
password is changed. Please login to this user and change the password as
|
||||
your first step.
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
60
package-lock.json
generated
60
package-lock.json
generated
@ -43,7 +43,7 @@
|
||||
"dependencies": {
|
||||
"@heyputer/kv.js": "^0.1.3",
|
||||
"@heyputer/multest": "^0.0.2",
|
||||
"@heyputer/puter-js-common": "^1.0.0",
|
||||
"@heyputer/putility": "^1.0.0",
|
||||
"@opentelemetry/api": "^1.4.1",
|
||||
"@opentelemetry/auto-instrumentations-node": "^0.43.0",
|
||||
"@opentelemetry/exporter-trace-otlp-grpc": "^0.40.0",
|
||||
@ -195,7 +195,7 @@
|
||||
"webpack-cli": "^5.1.4"
|
||||
}
|
||||
},
|
||||
"asdf/puter-js-common": {
|
||||
"asdf/putility": {
|
||||
"version": "1.0.0",
|
||||
"extraneous": true,
|
||||
"license": "UNLICENSED"
|
||||
@ -2545,6 +2545,10 @@
|
||||
"resolved": "src/backend",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@heyputer/gui": {
|
||||
"resolved": "src/gui",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@heyputer/kv.js": {
|
||||
"version": "0.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@heyputer/kv.js/-/kv.js-0.1.6.tgz",
|
||||
@ -2597,14 +2601,18 @@
|
||||
"resolved": "src/phoenix",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@heyputer/puter-js-common": {
|
||||
"resolved": "src/puter-js-common",
|
||||
"node_modules/@heyputer/puter-wisp": {
|
||||
"resolved": "src/puter-wisp",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@heyputer/puterjs": {
|
||||
"resolved": "src/puter-js",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@heyputer/putility": {
|
||||
"resolved": "src/putility",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@heyputer/terminal": {
|
||||
"resolved": "src/terminal",
|
||||
"link": true
|
||||
@ -12515,9 +12523,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/mocha": {
|
||||
"version": "10.6.0",
|
||||
"resolved": "https://registry.npmjs.org/mocha/-/mocha-10.6.0.tgz",
|
||||
"integrity": "sha512-hxjt4+EEB0SA0ZDygSS015t65lJw/I2yRCS3Ae+SJ5FrbzrXgfYwJr96f0OvIXdj7h4lv/vLCrH3rkiuizFSvw==",
|
||||
"version": "10.7.3",
|
||||
"resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.3.tgz",
|
||||
"integrity": "sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@ -15371,9 +15379,10 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/tiktoken": {
|
||||
"version": "1.0.15",
|
||||
"resolved": "https://registry.npmjs.org/tiktoken/-/tiktoken-1.0.15.tgz",
|
||||
"integrity": "sha512-sCsrq/vMWUSEW29CJLNmPvWxlVp7yh2tlkAjpJltIKqp5CKf98ZNpdeHRmAlPVFlGEbswDc6SmI8vz64W/qErw=="
|
||||
"version": "1.0.16",
|
||||
"resolved": "https://registry.npmjs.org/tiktoken/-/tiktoken-1.0.16.tgz",
|
||||
"integrity": "sha512-hRcORIGF2YlAgWx3nzrGJOrKSJwLoc81HpXmMQk89632XAgURc7IeV2FgQ2iXo9z/J96fCvpsHg2kWoHcbj9fg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/tildify": {
|
||||
"version": "2.0.0",
|
||||
@ -16441,7 +16450,7 @@
|
||||
"dependencies": {
|
||||
"@heyputer/kv.js": "^0.1.3",
|
||||
"@heyputer/multest": "^0.0.2",
|
||||
"@heyputer/puter-js-common": "^1.0.0",
|
||||
"@heyputer/putility": "^1.0.0",
|
||||
"@opentelemetry/api": "^1.4.1",
|
||||
"@opentelemetry/auto-instrumentations-node": "^0.43.0",
|
||||
"@opentelemetry/exporter-trace-otlp-grpc": "^0.40.0",
|
||||
@ -16616,8 +16625,8 @@
|
||||
"webpack-cli": "^5.1.4"
|
||||
}
|
||||
},
|
||||
"packages/puter-js-common": {
|
||||
"name": "@heyputer/puter-js-common",
|
||||
"packages/putility": {
|
||||
"name": "@heyputer/putility",
|
||||
"version": "1.0.0",
|
||||
"extraneous": true,
|
||||
"license": "UNLICENSED"
|
||||
@ -16661,7 +16670,7 @@
|
||||
"@aws-sdk/client-textract": "^3.621.0",
|
||||
"@heyputer/kv.js": "^0.1.3",
|
||||
"@heyputer/multest": "^0.0.2",
|
||||
"@heyputer/puter-js-common": "^1.0.0",
|
||||
"@heyputer/putility": "^1.0.0",
|
||||
"@mistralai/mistralai": "^1.0.3",
|
||||
"@opentelemetry/api": "^1.4.1",
|
||||
"@opentelemetry/auto-instrumentations-node": "^0.43.0",
|
||||
@ -16719,7 +16728,7 @@
|
||||
"string-hash": "^1.1.3",
|
||||
"string-length": "^6.0.0",
|
||||
"svgo": "^3.0.2",
|
||||
"tiktoken": "^1.0.15",
|
||||
"tiktoken": "^1.0.16",
|
||||
"together-ai": "^0.6.0-alpha.4",
|
||||
"tweetnacl": "^1.0.3",
|
||||
"ua-parser-js": "^1.0.38",
|
||||
@ -16785,8 +16794,8 @@
|
||||
}
|
||||
},
|
||||
"src/gui": {
|
||||
"version": "2.3.0",
|
||||
"extraneous": true,
|
||||
"name": "@heyputer/gui",
|
||||
"version": "2.4.0",
|
||||
"license": "AGPL-3.0-only",
|
||||
"workspaces": [
|
||||
"src/*"
|
||||
@ -16901,10 +16910,21 @@
|
||||
"webpack-cli": "^5.1.4"
|
||||
}
|
||||
},
|
||||
"src/puter-js-common": {
|
||||
"name": "@heyputer/puter-js-common",
|
||||
"src/puter-wisp": {
|
||||
"name": "@heyputer/puter-wisp",
|
||||
"version": "1.0.0",
|
||||
"license": "UNLICENSED"
|
||||
"license": "AGPL-3.0-only"
|
||||
},
|
||||
"src/putil": {
|
||||
"name": "@heyputer/putility",
|
||||
"version": "1.0.0",
|
||||
"extraneous": true,
|
||||
"license": "AGPL-3.0-only"
|
||||
},
|
||||
"src/putility": {
|
||||
"name": "@heyputer/putility",
|
||||
"version": "1.0.0",
|
||||
"license": "AGPL-3.0-only"
|
||||
},
|
||||
"src/strataparse": {
|
||||
"version": "0.0.0",
|
||||
|
@ -71,7 +71,7 @@ doing the useless work that reveals what the useful work is.
|
||||
|
||||
## Underlying Constructs
|
||||
|
||||
- [puter-js-common's README.md](../../packages/puter-js-common/README.md)
|
||||
- [putility's README.md](../../packages/putility/README.md)
|
||||
- Whenever you see `AdvancedBase`, that's from here
|
||||
- Many things in backend extend this. Anything that doesn't only doesn't
|
||||
because it was written before `AdvancedBase` existed.
|
||||
|
@ -35,7 +35,7 @@ To function properly, Puter needs **CoreModule**, a database module,
|
||||
and a storage module.
|
||||
|
||||
A module extends
|
||||
[AdvancedBase](../../../puter-js-common/README.md)
|
||||
[AdvancedBase](../../../putility/README.md)
|
||||
and implements
|
||||
an `install` method. The install method has one parameter, a
|
||||
[Context](../../src/util/context.js)
|
||||
|
@ -12,7 +12,7 @@
|
||||
"@aws-sdk/client-textract": "^3.621.0",
|
||||
"@heyputer/kv.js": "^0.1.3",
|
||||
"@heyputer/multest": "^0.0.2",
|
||||
"@heyputer/puter-js-common": "^1.0.0",
|
||||
"@heyputer/putility": "^1.0.0",
|
||||
"@mistralai/mistralai": "^1.0.3",
|
||||
"@opentelemetry/api": "^1.4.1",
|
||||
"@opentelemetry/auto-instrumentations-node": "^0.43.0",
|
||||
@ -70,7 +70,7 @@
|
||||
"string-hash": "^1.1.3",
|
||||
"string-length": "^6.0.0",
|
||||
"svgo": "^3.0.2",
|
||||
"tiktoken": "^1.0.15",
|
||||
"tiktoken": "^1.0.16",
|
||||
"together-ai": "^0.6.0-alpha.4",
|
||||
"tweetnacl": "^1.0.3",
|
||||
"ua-parser-js": "^1.0.38",
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("@heyputer/putility");
|
||||
const Library = require("./definitions/Library");
|
||||
const { NotificationES } = require("./om/entitystorage/NotificationES");
|
||||
const { ProtectedAppES } = require("./om/entitystorage/ProtectedAppES");
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("@heyputer/putility");
|
||||
|
||||
class DatabaseModule extends AdvancedBase {
|
||||
async install (context) {
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("@heyputer/putility");
|
||||
const { Context } = require('./util/context');
|
||||
const BaseService = require("./services/BaseService");
|
||||
const useapi = require('useapi');
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("@heyputer/putility");
|
||||
|
||||
class LocalDiskStorageModule extends AdvancedBase {
|
||||
async install (context) {
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("@heyputer/putility");
|
||||
|
||||
class PuterDriversModule extends AdvancedBase {
|
||||
async install () {}
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("@heyputer/putility");
|
||||
|
||||
class ThirdPartyDriversModule extends AdvancedBase {
|
||||
// constructor () {
|
||||
|
@ -482,6 +482,10 @@ module.exports = class APIError {
|
||||
status: 422,
|
||||
message: 'This share can not be applied to this user.',
|
||||
},
|
||||
'no_origin_for_app': {
|
||||
status: 400,
|
||||
message: 'Puter apps must have a valid URL.'
|
||||
},
|
||||
|
||||
// Chat
|
||||
// TODO: specifying these errors here might be a violation
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("@heyputer/putility");
|
||||
const { quot } = require("../util/strutil");
|
||||
const { TechnicalError } = require("../errors/TechnicalError");
|
||||
const { print_error_help } = require("../errors/error_help_details");
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("@heyputer/putility");
|
||||
const { quot } = require("../util/strutil");
|
||||
|
||||
class ConfigLoader extends AdvancedBase {
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("@heyputer/putility");
|
||||
const { Context } = require('../util/context')
|
||||
const APIError = require("../api/APIError");
|
||||
const { AppUnderUserActorType, UserActorType } = require("../services/auth/Actor");
|
||||
|
@ -27,7 +27,7 @@ const SystemFSEntryService = require('./storage/SystemFSEntryService.js');
|
||||
const PerformanceMonitor = require('../monitor/PerformanceMonitor.js');
|
||||
const { NodePathSelector, NodeUIDSelector, NodeInternalIDSelector } = require('./node/selectors.js');
|
||||
const FSNodeContext = require('./FSNodeContext.js');
|
||||
const { AdvancedBase } = require('@heyputer/puter-js-common');
|
||||
const { AdvancedBase } = require('@heyputer/putility');
|
||||
const { Context } = require('../util/context.js');
|
||||
const { simple_retry } = require('../util/retryutil.js');
|
||||
const APIError = require('../api/APIError.js');
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require('@heyputer/puter-js-common');
|
||||
const { AdvancedBase } = require('@heyputer/putility');
|
||||
const PathResolver = require('../../routers/filesystem_api/batch/PathResolver');
|
||||
const commands = require('./commands').commands;
|
||||
const { WorkUnit } = require('../../services/runtime-analysis/ExpectationService');
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("@heyputer/putility");
|
||||
const { AsyncProviderFeature } = require("../../traits/AsyncProviderFeature");
|
||||
const { HLMkdir, QuickMkdir } = require("../hl_operations/hl_mkdir");
|
||||
const { Context } = require("../../util/context");
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("@heyputer/putility");
|
||||
const { id2path } = require("../../helpers");
|
||||
|
||||
const { PuterPath } = require("../lib/PuterPath");
|
||||
|
@ -1,4 +1,4 @@
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("@heyputer/putility");
|
||||
|
||||
class BroadcastModule extends AdvancedBase {
|
||||
async install (context) {
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("@heyputer/putility");
|
||||
const BaseService = require("../../services/BaseService");
|
||||
const { CLink } = require("./connection/CLink");
|
||||
const { SLink } = require("./connection/SLink");
|
||||
|
@ -1,4 +1,4 @@
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("@heyputer/putility");
|
||||
const { ChannelFeature } = require("../../../traits/ChannelFeature");
|
||||
|
||||
class BaseLink extends AdvancedBase {
|
||||
|
@ -1,4 +1,4 @@
|
||||
const { AdvancedBase } = require('@heyputer/puter-js-common');
|
||||
const { AdvancedBase } = require('@heyputer/putility');
|
||||
|
||||
class KeyPairHelper extends AdvancedBase {
|
||||
static MODULES = {
|
||||
|
@ -90,6 +90,7 @@ class ClaudeService extends BaseService {
|
||||
});
|
||||
stream.write(str + '\n');
|
||||
}
|
||||
stream.end();
|
||||
})();
|
||||
|
||||
return retval;
|
||||
|
@ -54,6 +54,7 @@ class GroqAIService extends BaseService {
|
||||
});
|
||||
stream.write(str + '\n');
|
||||
}
|
||||
stream.end();
|
||||
})();
|
||||
return retval;
|
||||
}
|
||||
|
@ -55,6 +55,7 @@ class MistralAIService extends BaseService {
|
||||
});
|
||||
stream.write(str + '\n');
|
||||
}
|
||||
stream.end();
|
||||
})();
|
||||
return retval;
|
||||
}
|
||||
|
@ -91,8 +91,7 @@ class OpenAICompletionService extends BaseService {
|
||||
throw new Error('`messages` must be an array');
|
||||
}
|
||||
|
||||
model = model ?? 'gpt-3.5-turbo';
|
||||
// model = model ?? 'gpt-4o';
|
||||
model = model ?? 'gpt-4o-mini';
|
||||
|
||||
for ( let i = 0; i < messages.length; i++ ) {
|
||||
let msg = messages[i];
|
||||
@ -233,6 +232,7 @@ class OpenAICompletionService extends BaseService {
|
||||
});
|
||||
stream.write(str + '\n');
|
||||
}
|
||||
stream.end();
|
||||
})();
|
||||
return retval;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("@heyputer/putility");
|
||||
const config = require("../../config");
|
||||
|
||||
class PuterAIModule extends AdvancedBase {
|
||||
|
@ -59,6 +59,7 @@ class TogetherAIService extends BaseService {
|
||||
});
|
||||
stream.write(str + '\n');
|
||||
}
|
||||
stream.end();
|
||||
})();
|
||||
return retval;
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ const DEFAULT_FILES = {
|
||||
}
|
||||
},
|
||||
"es": {
|
||||
"date-limit": {
|
||||
"rate-limit": {
|
||||
"max": 1000,
|
||||
"period": 30000
|
||||
}
|
||||
@ -90,7 +90,18 @@ class DefaultUserService extends BaseService {
|
||||
if ( ! is_default_password ) return;
|
||||
|
||||
// show console widget
|
||||
this.default_user_widget = () => {
|
||||
this.default_user_widget = ({ is_docker }) => {
|
||||
if ( is_docker ) {
|
||||
// In Docker we keep the output as simple as possible because
|
||||
// we're unable to determine the size of the terminal
|
||||
return [
|
||||
'Password for `admin`: ' + tmp_password,
|
||||
// TODO: possible bug
|
||||
// These blank lines are necessary for it to render and
|
||||
// I'm not entirely sure why anymore.
|
||||
'', '',
|
||||
];
|
||||
}
|
||||
const lines = [
|
||||
`Your admin user has been created!`,
|
||||
`\x1B[31;1musername:\x1B[0m ${USERNAME}`,
|
||||
@ -100,6 +111,7 @@ class DefaultUserService extends BaseService {
|
||||
surrounding_box('31;1', lines);
|
||||
return lines;
|
||||
};
|
||||
this.default_user_widget.critical = true;
|
||||
this.start_poll_({ tmp_password, user });
|
||||
const svc_devConsole = this.services.get('dev-console');
|
||||
svc_devConsole.add_widget(this.default_user_widget);
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("@heyputer/putility");
|
||||
const config = require("../../config");
|
||||
|
||||
class SelfHostedModule extends AdvancedBase {
|
||||
@ -48,6 +48,12 @@ class SelfHostedModule extends AdvancedBase {
|
||||
command: 'npm',
|
||||
args: ['run', 'start-webpack'],
|
||||
},
|
||||
{
|
||||
name: 'gui:webpack-watch',
|
||||
directory: 'src/gui',
|
||||
command: 'npm',
|
||||
args: ['run', 'start-webpack'],
|
||||
},
|
||||
{
|
||||
name: 'terminal:rollup-watch',
|
||||
directory: 'src/terminal',
|
||||
@ -111,6 +117,18 @@ class SelfHostedModule extends AdvancedBase {
|
||||
'src/puter-js/dist/puter.dev.js'),
|
||||
route: '/puter.js/v2',
|
||||
});
|
||||
services.registerService('__serve-putilityjs-new', ServeSingleFileService, {
|
||||
path: path_.resolve(__dirname,
|
||||
RELATIVE_PATH,
|
||||
'src/putility/dist/putility.dev.js'),
|
||||
route: '/putility.js/v1',
|
||||
});
|
||||
services.registerService('__serve-gui-js', ServeSingleFileService, {
|
||||
path: path_.resolve(__dirname,
|
||||
RELATIVE_PATH,
|
||||
'src/gui/dist/gui.dev.js'),
|
||||
route: '/putility.js/v1',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("@heyputer/putility");
|
||||
|
||||
class TestDriversModule extends AdvancedBase {
|
||||
async install (context) {
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("@heyputer/putility");
|
||||
const { WeakConstructorFeature } = require("../traits/WeakConstructorFeature");
|
||||
const { Eq, And } = require("./query/query");
|
||||
const { Entity } = require("./entitystorage/Entity");
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("@heyputer/putility");
|
||||
const { instance_ } = require("../../monitor/PerformanceMonitor");
|
||||
const { WeakConstructorFeature } = require("../../traits/WeakConstructorFeature");
|
||||
const { Property } = require("./Property");
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("@heyputer/putility");
|
||||
const { WeakConstructorFeature } = require("../../traits/WeakConstructorFeature");
|
||||
|
||||
class PropType extends AdvancedBase {
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("@heyputer/putility");
|
||||
const { WeakConstructorFeature } = require("../../traits/WeakConstructorFeature");
|
||||
|
||||
class Property extends AdvancedBase {
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("@heyputer/putility");
|
||||
const { WeakConstructorFeature } = require("../../traits/WeakConstructorFeature");
|
||||
const { Context } = require("../../util/context");
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("@heyputer/putility");
|
||||
const { WeakConstructorFeature } = require("../../traits/WeakConstructorFeature");
|
||||
|
||||
class Entity extends AdvancedBase {
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("@heyputer/putility");
|
||||
const { BaseES } = require("./BaseES");
|
||||
|
||||
const APIError = require("../../api/APIError");
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("@heyputer/putility");
|
||||
const { BaseES } = require("./BaseES");
|
||||
|
||||
const APIError = require("../../api/APIError");
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("@heyputer/putility");
|
||||
const { WeakConstructorFeature } = require("../../traits/WeakConstructorFeature");
|
||||
|
||||
class Predicate extends AdvancedBase {
|
||||
|
@ -87,6 +87,13 @@ router.all('*', async function(req, res, next) {
|
||||
}
|
||||
});
|
||||
}
|
||||
if (path === '/putility/v1') {
|
||||
return res.sendFile(_path.join(__dirname, config.defaultjs_asset_path, 'putility.js/v1.js'), function (err) {
|
||||
if (err && err.statusCode) {
|
||||
return res.status(err.statusCode).send('Error /putility.js')
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const db = Context.get('services').get('database').get(DB_READ, 'default');
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("@heyputer/putility");
|
||||
const api_error_handler = require("../../api/api_error_handler");
|
||||
const config = require("../../config");
|
||||
const { get_user, get_app, id2path } = require("../../helpers");
|
||||
|
@ -117,7 +117,7 @@ module.exports = eggspress('/sign', {
|
||||
|
||||
if ( item.action === 'write' ) {
|
||||
if ( ! await svc_acl.check(actor, node, 'write') ) {
|
||||
throw await svc_acl.get_safe_acl_error(actor, node, 'write');
|
||||
item.action = 'read';
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("../../../putility");
|
||||
|
||||
const NOOP = async () => {};
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("@heyputer/putility");
|
||||
const config = require("../config");
|
||||
const { Context } = require("../util/context");
|
||||
const { CompositeError } = require("../util/errorutil");
|
||||
|
@ -20,11 +20,26 @@ const { consoleLogManager } = require('../util/consolelog');
|
||||
const BaseService = require('./BaseService');
|
||||
|
||||
class DevConsoleService extends BaseService {
|
||||
static MODULES = {
|
||||
fs: require('fs'),
|
||||
}
|
||||
|
||||
_construct () {
|
||||
this.static_lines = [];
|
||||
this.widgets = [];
|
||||
this.identifiers = {};
|
||||
this.has_updates = false;
|
||||
|
||||
try {
|
||||
const require = this.require;
|
||||
const fs = require('fs');
|
||||
this.is_docker = fs.existsSync('/.dockerenv');
|
||||
} catch (e) {
|
||||
// if this fails, we assume is_docker should
|
||||
// be false.
|
||||
this.log.error(e.message);
|
||||
this.is_docker = false;
|
||||
}
|
||||
}
|
||||
|
||||
turn_on_the_warning_lights () {
|
||||
@ -60,7 +75,7 @@ class DevConsoleService extends BaseService {
|
||||
let positions = [];
|
||||
for ( const w of this.widgets ) {
|
||||
let output; try {
|
||||
output = w();
|
||||
output = w({ is_docker: this.is_docker });
|
||||
} catch ( e ) {
|
||||
consoleLogManager.log_raw('error', e);
|
||||
to_remove.push(w);
|
||||
@ -78,6 +93,7 @@ class DevConsoleService extends BaseService {
|
||||
for ( let i = this.widgets.length-1 ; i >= 0 ; i-- ) {
|
||||
if ( size_ok() ) break;
|
||||
const w = this.widgets[i];
|
||||
if ( w.critical ) continue;
|
||||
if ( ! w.unimportant ) continue;
|
||||
n_hidden++;
|
||||
const [start, length] = positions[i];
|
||||
@ -89,8 +105,9 @@ class DevConsoleService extends BaseService {
|
||||
}
|
||||
for ( let i = this.widgets.length-1 ; i >= 0 ; i-- ) {
|
||||
if ( size_ok() ) break;
|
||||
n_hidden++;
|
||||
const w = this.widgets[i];
|
||||
if ( w.critical ) continue;
|
||||
n_hidden++;
|
||||
const [start, length] = positions[i];
|
||||
this.static_lines.splice(start, length);
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("@heyputer/putility");
|
||||
|
||||
class EngPortalService extends AdvancedBase {
|
||||
static MODULES = {
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("../../../putility");
|
||||
const { Context } = require("../util/context");
|
||||
const { ContextAwareFeature } = require("../traits/ContextAwareFeature");
|
||||
const { OtelFeature } = require("../traits/OtelFeature");
|
||||
|
@ -255,46 +255,9 @@ class PuterHomepageService extends BaseService {
|
||||
? `<script>window.gui_env = 'prod';</script>`
|
||||
: ''
|
||||
}
|
||||
${
|
||||
((!bundled && manifest?.lib_paths)
|
||||
? manifest.lib_paths.map(path => `<script type="text/javascript" src="${path}"></script>\n`)
|
||||
: []).join('')
|
||||
}
|
||||
|
||||
<script>
|
||||
window.icons = {};
|
||||
|
||||
${(() => {
|
||||
if ( !(!bundled && manifest) ) return '';
|
||||
const html = [];
|
||||
fs_.readdirSync(path_.join(gui_path, 'src/icons')).forEach(file => {
|
||||
// skip dotfiles
|
||||
if(file.startsWith('.'))
|
||||
return;
|
||||
// load image
|
||||
let buff = new Buffer.from(fs_.readFileSync(path_.join(gui_path, 'src/icons') + '/' + file));
|
||||
// convert to base64
|
||||
let base64data = buff.toString('base64');
|
||||
// add to `window.icons`
|
||||
if(file.endsWith('.png'))
|
||||
html.push(`window.icons['${file}'] = "data:image/png;base64,${base64data}";\n`);
|
||||
else if(file.endsWith('.svg'))
|
||||
html.push(`window.icons['${file}'] = "data:image/svg+xml;base64,${base64data}";\n`);
|
||||
})
|
||||
return html.join('');
|
||||
})()}
|
||||
</script>
|
||||
|
||||
${
|
||||
((!bundled && manifest?.js_paths)
|
||||
? manifest.js_paths.map(path => writeScriptTag(path))
|
||||
: []).join('')
|
||||
}
|
||||
<!-- Load the GUI script -->
|
||||
<script ${
|
||||
// !bundled ? ' type="module"' : ''
|
||||
' type="module"'
|
||||
} src="${(!bundled && manifest?.index) || '/dist/gui.js'}"></script>
|
||||
<script src="/dist/bundle.min.js"></script>
|
||||
<!-- Initialize GUI when document is loaded -->
|
||||
<script type="module">
|
||||
window.addEventListener('load', function() {
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("@heyputer/putility");
|
||||
const BaseService = require("./BaseService");
|
||||
|
||||
class MapCollection extends AdvancedBase {
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("@heyputer/putility");
|
||||
|
||||
class ServicePatch extends AdvancedBase {
|
||||
patch ({ original_service }) {
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("@heyputer/putility");
|
||||
|
||||
class StorageService extends AdvancedBase {
|
||||
constructor ({ services }) {
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("@heyputer/putility");
|
||||
|
||||
class WSPushService extends AdvancedBase {
|
||||
static MODULES = {
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("@heyputer/putility");
|
||||
const BaseService = require("../BaseService");
|
||||
const { Context } = require("../../util/context");
|
||||
const config = require("../../config");
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("../../../../putility");
|
||||
const { Context } = require("../../util/context");
|
||||
const { get_user, get_app } = require("../../helpers");
|
||||
const config = require("../../config");
|
||||
|
@ -442,6 +442,9 @@ class AuthService extends BaseService {
|
||||
|
||||
async app_uid_from_origin (origin) {
|
||||
origin = this._origin_from_url(origin);
|
||||
if ( origin === null ) {
|
||||
throw APIError.create('no_origin_for_app');
|
||||
}
|
||||
return await this._app_uid_from_origin(origin);
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("../../../../putility");
|
||||
const BaseService = require("../BaseService");
|
||||
const { DB_WRITE, DB_READ } = require("./consts");
|
||||
|
||||
|
@ -23,7 +23,7 @@ const { TypedValue } = require("./meta/Runtime");
|
||||
const BaseService = require("../BaseService");
|
||||
const { Driver } = require("../../definitions/Driver");
|
||||
const { PermissionUtil } = require("../auth/PermissionService");
|
||||
const { Invoker } = require("@heyputer/puter-js-common/src/libs/invoker");
|
||||
const { Invoker } = require("../../../../putility/src/libs/invoker");
|
||||
const { get_user } = require("../../helpers");
|
||||
|
||||
/**
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("../../../../putility");
|
||||
const { Context } = require("../../util/context");
|
||||
const { MultiValue } = require("../../util/multivalue");
|
||||
const { stream_to_buffer } = require("../../util/streamutil");
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { BasicBase } = require("@heyputer/puter-js-common/src/bases/BasicBase");
|
||||
const { BasicBase } = require("../../../../../putility/src/bases/BasicBase");
|
||||
const types = require("../types");
|
||||
const { hash_serializable_object, stringify_serializable_object } = require("../../../util/datautil");
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { BasicBase } = require("@heyputer/puter-js-common/src/bases/BasicBase");
|
||||
const { BasicBase } = require("../../../../../putility/src/bases/BasicBase");
|
||||
const { TypeSpec } = require("./Construct");
|
||||
|
||||
class RuntimeEntity extends BasicBase {
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("../../../../putility");
|
||||
const { is_valid_path } = require("../../filesystem/validation");
|
||||
const { is_valid_url, is_valid_uuid4 } = require("../../helpers");
|
||||
const { FileFacade } = require("./FileFacade");
|
||||
|
@ -17,7 +17,7 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const TeePromise = require("@heyputer/multest/src/util/TeePromise");
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("@heyputer/putility");
|
||||
const { FileTracker } = require("./FileTracker");
|
||||
const { pausing_tee } = require("../../util/streamutil");
|
||||
|
||||
|
@ -462,6 +462,11 @@ class LogService extends BaseService {
|
||||
{
|
||||
const fs = require('fs');
|
||||
const path = '/var/puter/logs/heyputer';
|
||||
// Making this directory if it doesn't exist causes issues
|
||||
// for users running with development instructions
|
||||
if ( ! fs.existsSync('/var/puter') ) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
fs.mkdirSync(path, { recursive: true });
|
||||
this.log_directory = path;
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("@heyputer/putility");
|
||||
const APIError = require("../../api/APIError");
|
||||
const { Context } = require("../../util/context");
|
||||
const BaseService = require("../BaseService");
|
||||
|
@ -22,7 +22,7 @@
|
||||
const axios = require('axios');
|
||||
|
||||
const { TeePromise } = require("../../util/promise");
|
||||
const { AdvancedBase } = require('@heyputer/puter-js-common');
|
||||
const { AdvancedBase } = require('@heyputer/putility');
|
||||
const FormData = require("form-data");
|
||||
const { stream_to_the_void, buffer_to_stream } = require('../../util/streamutil');
|
||||
const BaseService = require('../BaseService');
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("../../../putility");
|
||||
|
||||
/**
|
||||
* MutliValue represents a subject with multiple values or a value with multiple
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("../../../putility");
|
||||
|
||||
/**
|
||||
* PathBuilder implements the builder pattern for building paths.
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
const { AdvancedBase } = require("@heyputer/puter-js-common");
|
||||
const { AdvancedBase } = require("@heyputer/putility");
|
||||
const useapi = require("useapi");
|
||||
const { BaseService } = require("../exports");
|
||||
const CoreModule = require("../src/CoreModule");
|
||||
|
@ -264,6 +264,7 @@ section {
|
||||
|
||||
label, input[type="text"] {
|
||||
display: block;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
#delete-app {
|
||||
@ -854,7 +855,11 @@ ol li:before {
|
||||
float:right; margin-bottom: 10px;
|
||||
}
|
||||
.edit-app-navbar{
|
||||
overflow: hidden; margin-bottom: 60px; margin-top: 20px;
|
||||
overflow: hidden;
|
||||
margin-bottom: 60px;
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.app-title{
|
||||
margin-top:0px;
|
||||
|
@ -245,7 +245,7 @@
|
||||
<script src="./js/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
|
||||
crossorigin="anonymous"></script>
|
||||
<script src="./js/jquery.dragster.js"></script>
|
||||
<script src="/puter.js/v2"></script>
|
||||
<script src="https://js.puter.com/v2"></script>
|
||||
<script src="./js/slugify.js"></script>
|
||||
<script type="module" src="./js/html-entities.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
|
||||
|
@ -440,7 +440,7 @@ function generate_edit_app_section(app) {
|
||||
let h = ``;
|
||||
h += `
|
||||
<div class="edit-app-navbar">
|
||||
<div style="float:left; min-width: 700px;">
|
||||
<div style="flex-grow:1;">
|
||||
<img class="app-icon" data-uid="${html_encode(app.uid)}" src="${html_encode(!app.icon ? './img/app.svg' : app.icon)}">
|
||||
<h3 class="app-title" data-uid="${html_encode(app.uid)}">${html_encode(app.title)}</h3>
|
||||
<div style="margin-top: 4px; margin-bottom: 4px;">
|
||||
@ -475,6 +475,7 @@ function generate_edit_app_section(app) {
|
||||
<div class="success" id="edit-app-success">App has been successfully updated.<span class="close-success-msg">×</span></div>
|
||||
<input type="hidden" id="edit-app-uid" value="${html_encode(app.uid)}">
|
||||
|
||||
<h3 style="border-bottom: 1px solid #EEE; margin-top: 40px;">Basic Info</h3>
|
||||
<label for="edit-app-title">Title</label>
|
||||
<input type="text" id="edit-app-title" placeholder="My Awesome App!" value="${html_encode(app.title)}">
|
||||
|
||||
@ -487,45 +488,6 @@ function generate_edit_app_section(app) {
|
||||
<label for="edit-app-app-id">App ID</label>
|
||||
<input type="text" style="width: 362px;" class="app-uid" value="${html_encode(app.uid)}" readonly>
|
||||
|
||||
<div>
|
||||
<input type="checkbox" id="edit-app-background" name="edit-app-background" value="true" style="margin-top:30px;" ${app.background ? 'checked' : ''}>
|
||||
<label for="edit-app-background" style="display: inline;">Run as a background process.</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<input type="checkbox" id="edit-app-fullpage-on-landing" name="edit-app-fullpage-on-landing" value="true" style="margin-top:30px;" ${app.metadata?.fullpage_on_landing ? 'checked' : ''}>
|
||||
<label for="edit-app-fullpage-on-landing" style="display: inline;">Load in full-page mode when a user lands directly on this app.</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<input type="checkbox" id="edit-app-maximize-on-start" name="edit-app-maximize-on-start" value="true" style="margin-top:30px;" ${maximize_on_start ? 'checked' : ''}>
|
||||
<label for="edit-app-maximize-on-start" style="display: inline;">Maximize window on start</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="edit-app-window-width">Window Width</label>
|
||||
<input type="number" id="edit-app-window-width" placeholder="800" value="${html_encode(app.metadata?.window_size?.width ?? 800)}" style="width:200px;" ${maximize_on_start ? 'disabled' : ''}>
|
||||
<label for="edit-app-window-height">Window Height</label>
|
||||
<input type="number" id="edit-app-window-height" placeholder="600" value="${html_encode(app.metadata?.window_size?.height ?? 600)}" style="width:200px;" ${maximize_on_start ? 'disabled' : ''}>
|
||||
</div>
|
||||
|
||||
<div style="margin-top:30px;">
|
||||
<label for="edit-app-window-top">Window Top</label>
|
||||
<input type="number" id="edit-app-window-top" placeholder="100" value="${app.metadata?.window_position?.top ? html_encode(app.metadata.window_position.top) : ''}" style="width:200px;" ${maximize_on_start ? 'disabled' : ''}>
|
||||
<label for="edit-app-window-left">Window Left</label>
|
||||
<input type="number" id="edit-app-window-left" placeholder="100" value="${app.metadata?.window_position?.left ? html_encode(app.metadata.window_position.left) : ''}" style="width:200px;" ${maximize_on_start ? 'disabled' : ''}>
|
||||
</div>
|
||||
|
||||
<div style="margin-top:30px;">
|
||||
<input type="checkbox" id="edit-app-window-resizable" name="edit-app-window-resizable" value="true" ${app.metadata?.window_resizable ? 'checked' : ''}>
|
||||
<label for="edit-app-window-resizable" style="display: inline;">Window Resizable</label>
|
||||
</div>
|
||||
|
||||
<div style="margin-top:30px;">
|
||||
<input type="checkbox" id="edit-app-hide-titlebar" name="edit-app-hide-titlebar" value="true" ${app.metadata?.hide_titlebar ? 'checked' : ''}>
|
||||
<label for="edit-app-hide-titlebar" style="display: inline;">Hide Titlebar</label>
|
||||
</div>
|
||||
|
||||
<label for="edit-app-icon">Icon</label>
|
||||
<div id="edit-app-icon" style="background-image:url(${!app.icon ? './img/app.svg' : html_encode(app.icon)});" ${app.icon ? 'data-url="' + html_encode(app.icon) + '"' : ''}>
|
||||
<div id="change-app-icon">Change App Icon</div>
|
||||
@ -539,6 +501,47 @@ function generate_edit_app_section(app) {
|
||||
<p style="margin-top: 10px; font-size:13px;">A comma-separated list of file type specifiers. For example if you include <code>.txt</code>, your apps could be opened when a user clicks on a TXT file.</p>
|
||||
<textarea id="edit-app-filetype-associations" placeholder=".txt, .jpg, application/json">${app.filetype_associations}</textarea>
|
||||
|
||||
<h3 style="border-bottom: 1px solid #EEE; margin-top: 50px; margin-bottom: 0px;">Window Settings</h3>
|
||||
<div>
|
||||
<input type="checkbox" id="edit-app-background" name="edit-app-background" value="true" style="margin-top:30px;" ${app.background ? 'checked' : ''}>
|
||||
<label for="edit-app-background" style="display: inline;">Run as a background process.</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<input type="checkbox" id="edit-app-fullpage-on-landing" name="edit-app-fullpage-on-landing" value="true" style="margin-top:30px;" ${app.metadata?.fullpage_on_landing ? 'checked' : ''} ${app.background ? 'disabled' : ''}>
|
||||
<label for="edit-app-fullpage-on-landing" style="display: inline;">Load in full-page mode when a user lands directly on this app.</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<input type="checkbox" id="edit-app-maximize-on-start" name="edit-app-maximize-on-start" value="true" style="margin-top:30px;" ${maximize_on_start ? 'checked' : ''} ${app.background ? 'disabled' : ''}>
|
||||
<label for="edit-app-maximize-on-start" style="display: inline;">Maximize window on start</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label for="edit-app-window-width">Initial window width</label>
|
||||
<input type="number" id="edit-app-window-width" placeholder="680" value="${html_encode(app.metadata?.window_size?.width ?? 680)}" style="width:200px;" ${maximize_on_start || app.background ? 'disabled' : ''}>
|
||||
<label for="edit-app-window-height">Initial window height</label>
|
||||
<input type="number" id="edit-app-window-height" placeholder="380" value="${html_encode(app.metadata?.window_size?.height ?? 380)}" style="width:200px;" ${maximize_on_start || app.background ? 'disabled' : ''}>
|
||||
</div>
|
||||
|
||||
<div style="margin-top:30px;">
|
||||
<label for="edit-app-window-top">Initial window top</label>
|
||||
<input type="number" id="edit-app-window-top" placeholder="100" value="${app.metadata?.window_position?.top ? html_encode(app.metadata.window_position.top) : ''}" style="width:200px;" ${maximize_on_start || app.background ? 'disabled' : ''}>
|
||||
<label for="edit-app-window-left">Initial window left</label>
|
||||
<input type="number" id="edit-app-window-left" placeholder="100" value="${app.metadata?.window_position?.left ? html_encode(app.metadata.window_position.left) : ''}" style="width:200px;" ${maximize_on_start || app.background ? 'disabled' : ''}>
|
||||
</div>
|
||||
|
||||
<div style="margin-top:30px;">
|
||||
<input type="checkbox" id="edit-app-window-resizable" name="edit-app-window-resizable" value="true" ${app.metadata?.window_resizable ? 'checked' : ''} ${app.background ? 'disabled' : ''}>
|
||||
<label for="edit-app-window-resizable" style="display: inline;">Resizable window</label>
|
||||
</div>
|
||||
|
||||
<div style="margin-top:30px;">
|
||||
<input type="checkbox" id="edit-app-hide-titlebar" name="edit-app-hide-titlebar" value="true" ${app.metadata?.hide_titlebar ? 'checked' : ''} ${app.background ? 'disabled' : ''}>
|
||||
<label for="edit-app-hide-titlebar" style="display: inline;">Hide window titlebar</label>
|
||||
</div>
|
||||
|
||||
<hr style="margin-top: 40px;">
|
||||
<button type="button" class="edit-app-save-btn button button-primary">Save</button>
|
||||
</form>
|
||||
</div>
|
||||
@ -1108,7 +1111,7 @@ $(document).on('click', '#edit-app-icon', async function (e) {
|
||||
let mimeType = getMimeType(fileExtension);
|
||||
|
||||
// Replace MIME type in the data URL
|
||||
image = image.replace('data:application/octet-stream;base64', `data:image/${mimeType};base64`);
|
||||
image = image.replace('data:application/octet-stream;base64', `data:${mimeType};base64`);
|
||||
|
||||
$('#edit-app-icon').css('background-image', `url(${image})`);
|
||||
$('#edit-app-icon').attr('data-base64', image);
|
||||
@ -1315,11 +1318,31 @@ function sort_apps() {
|
||||
let sorted_apps;
|
||||
|
||||
// sort
|
||||
if (sortDirection === 'asc')
|
||||
sorted_apps = apps.sort((a, b) => a[sortBy] > b[sortBy] ? 1 : -1);
|
||||
else
|
||||
sorted_apps = apps.sort((a, b) => a[sortBy] < b[sortBy] ? 1 : -1);
|
||||
|
||||
if (sortDirection === 'asc'){
|
||||
sorted_apps = apps.sort((a, b) => {
|
||||
if(sortBy === 'name'){
|
||||
return a[sortBy].localeCompare(b[sortBy]);
|
||||
}else if(sortBy === 'created_at'){
|
||||
return new Date(a[sortBy]) - new Date(b[sortBy]);
|
||||
} else if(sortBy === 'user_count' || sortBy === 'open_count'){
|
||||
return a.stats[sortBy] - b.stats[sortBy];
|
||||
}else{
|
||||
a[sortBy] > b[sortBy] ? 1 : -1
|
||||
}
|
||||
});
|
||||
}else{
|
||||
sorted_apps = apps.sort((a, b) => {
|
||||
if(sortBy === 'name'){
|
||||
return b[sortBy].localeCompare(a[sortBy]);
|
||||
}else if(sortBy === 'created_at'){
|
||||
return new Date(b[sortBy]) - new Date(a[sortBy]);
|
||||
} else if(sortBy === 'user_count' || sortBy === 'open_count'){
|
||||
return b.stats[sortBy] - a.stats[sortBy];
|
||||
}else{
|
||||
b[sortBy] > a[sortBy] ? 1 : -1
|
||||
}
|
||||
});
|
||||
}
|
||||
// refresh app list
|
||||
$('.app-card').remove();
|
||||
sorted_apps.forEach(app => {
|
||||
@ -2084,4 +2107,30 @@ $(document).on('change', '#edit-app-maximize-on-start', function (e) {
|
||||
$('#edit-app-window-width, #edit-app-window-height').prop('disabled', false);
|
||||
$('#edit-app-window-top, #edit-app-window-left').prop('disabled', false);
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
$(document).on('change', '#edit-app-background', function (e) {
|
||||
if($('#edit-app-background').is(":checked")){
|
||||
disable_window_settings()
|
||||
}else{
|
||||
enable_window_settings()
|
||||
}
|
||||
})
|
||||
|
||||
function disable_window_settings(){
|
||||
$('#edit-app-maximize-on-start').prop('disabled', true);
|
||||
$('#edit-app-fullpage-on-landing').prop('disabled', true);
|
||||
$('#edit-app-window-width, #edit-app-window-height').prop('disabled', true);
|
||||
$('#edit-app-window-top, #edit-app-window-left').prop('disabled', true);
|
||||
$('#edit-app-window-resizable').prop('disabled', true);
|
||||
$('#edit-app-hide-titlebar').prop('disabled', true);
|
||||
}
|
||||
|
||||
function enable_window_settings(){
|
||||
$('#edit-app-maximize-on-start').prop('disabled', false);
|
||||
$('#edit-app-fullpage-on-landing').prop('disabled', false);
|
||||
$('#edit-app-window-width, #edit-app-window-height').prop('disabled', false);
|
||||
$('#edit-app-window-top, #edit-app-window-left').prop('disabled', false);
|
||||
$('#edit-app-window-resizable').prop('disabled', false);
|
||||
$('#edit-app-hide-titlebar').prop('disabled', false);
|
||||
}
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { PosixError } from '@heyputer/puter-js-common/src/PosixError.js';
|
||||
import { PosixError } from '@heyputer/putility/src/PosixError.js';
|
||||
import path_ from 'path-browserify';
|
||||
|
||||
let debug = false;
|
||||
|
81
src/gui/doc/webpack_attempts.md
Normal file
81
src/gui/doc/webpack_attempts.md
Normal file
@ -0,0 +1,81 @@
|
||||
Multiple things attempted when trying to add icons to the bundle.
|
||||
|
||||
None of this worked - eventually just prepended text on emit instead.
|
||||
|
||||
```javascript
|
||||
// compilation.hooks.processAssets.tap(
|
||||
// {
|
||||
// name: 'AddImportPlugin',
|
||||
// stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONS,
|
||||
// },
|
||||
// (assets) => {
|
||||
// for (const assetName of Object.keys(assets)) {
|
||||
// if (assetName.endsWith('.js')) {
|
||||
// const source = assets[assetName].source();
|
||||
// const newSource = `${icons}\n${source}`;
|
||||
// compilation.updateAsset(assetName, new compiler.webpack.sources.RawSource(newSource));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// );
|
||||
|
||||
// Inject into bundle
|
||||
// console.log('adding this:' + icons);
|
||||
// compilation.assets['icons-thing'] = {
|
||||
// source: () => icons,
|
||||
// size: () => icons.length,
|
||||
// };
|
||||
|
||||
// compilation.addModule({
|
||||
// identifier() {
|
||||
// return 'icons-thing';
|
||||
// },
|
||||
// build() {
|
||||
// this._source = {
|
||||
// source() {
|
||||
// return content;
|
||||
// },
|
||||
// size() {
|
||||
// return content.length;
|
||||
// }
|
||||
// };
|
||||
// }
|
||||
// });
|
||||
|
||||
|
||||
// Add the generated module to Webpack's internal modules
|
||||
// compilation.hooks.optimizeModules.tap('IconsPlugin', (modules) => {
|
||||
// const virtualModule = {
|
||||
// identifier: () => 'icons.js',
|
||||
// readableIdentifier: () => 'icons.js',
|
||||
// build: () => {},
|
||||
// source: () => icons,
|
||||
// size: () => icons.length,
|
||||
// chunks: [],
|
||||
// assets: [],
|
||||
// hash: () => 'icons',
|
||||
// };
|
||||
|
||||
// modules.push(virtualModule);
|
||||
// });
|
||||
|
||||
});
|
||||
// this.hooks.entryOption.tap('IconsPlugin', (context, entry) => {
|
||||
// entry.main.import.push('icons-thing');
|
||||
// });
|
||||
// this.hooks.make.tapAsync('InjectTextEntryPlugin', (compilation, callback) => {
|
||||
// // Create a new asset (fake module) from the generated content
|
||||
// const content = `console.log('${this.options.text}');`;
|
||||
|
||||
// callback();
|
||||
// });
|
||||
// this.hooks.entryOption.tap('IconsPlugin', (context, entry) => {
|
||||
// });
|
||||
// this.hooks.entryOption.tap('InjectTextEntryPlugin', (context, entry) => {
|
||||
// // Add this as an additional entry point
|
||||
// this.options.entry = {
|
||||
// ...this.options.entry,
|
||||
// 'generated-entry': '// FINDME\n'
|
||||
// };
|
||||
// });
|
||||
```
|
@ -28,7 +28,8 @@
|
||||
"test": "mocha ./packages/phoenix/test ./packages/phoenix/packages/contextlink/test",
|
||||
"start=gui": "nodemon --exec \"node dev-server.js\" ",
|
||||
"build": "node ./build.js",
|
||||
"check-translations": "node tools/check-translations.js"
|
||||
"check-translations": "node tools/check-translations.js",
|
||||
"start-webpack": "webpack --watch --devtool source-map"
|
||||
},
|
||||
"workspaces": [
|
||||
"src/*"
|
@ -10,7 +10,6 @@
|
||||
"/lib/jquery-ui-1.13.2/jquery-ui.min.js",
|
||||
"/lib/lodash@4.17.21.min.js",
|
||||
"/lib/jquery.dragster.js",
|
||||
"/lib/jquery.menu-aim.js",
|
||||
"/lib/html-entities.js",
|
||||
"/lib/timeago.min.js",
|
||||
"/lib/iro.min.js",
|
||||
|
@ -29,9 +29,9 @@ import download from './helpers/download.js';
|
||||
import path from "./lib/path.js";
|
||||
import UIContextMenu from './UI/UIContextMenu.js';
|
||||
import update_mouse_position from './helpers/update_mouse_position.js';
|
||||
import launch_app from './helpers/launch_app.js';
|
||||
import item_icon from './helpers/item_icon.js';
|
||||
|
||||
window.ipc_handlers = {};
|
||||
/**
|
||||
* In Puter, apps are loaded in iframes and communicate with the graphical user interface (GUI), and each other, using the postMessage API.
|
||||
* The following sets up an Inter-Process Messaging System between apps and the GUI that enables communication
|
||||
@ -88,6 +88,24 @@ window.addEventListener('message', async (event) => {
|
||||
const msg_id = event.data.uuid;
|
||||
const app_name = $(target_iframe).attr('data-app');
|
||||
const app_uuid = $el_parent_window.attr('data-app_uuid');
|
||||
|
||||
// New IPC handlers should be registered here.
|
||||
// Do this by calling `register_ipc_handler` of IPCService.
|
||||
if ( window.ipc_handlers.hasOwnProperty(event.data.msg) ) {
|
||||
// The IPC context contains information about the call
|
||||
const ipc_context = {
|
||||
appInstanceId: event.data.appInstanceID,
|
||||
};
|
||||
|
||||
// Registered IPC handlers are an object with a `handle()`
|
||||
// method. We call it "spec" here, meaning specification.
|
||||
const spec = window.ipc_handlers[event.data.msg];
|
||||
await spec.handler(event.data, { msg_id, ipc_context });
|
||||
|
||||
// Early-return to avoid redundant invokation of any
|
||||
// legacy IPC handler.
|
||||
return;
|
||||
}
|
||||
|
||||
// todo validate all event.data stuff coming from the client (e.g. event.data.message, .msg, ...)
|
||||
//-------------------------------------------------
|
||||
@ -846,25 +864,6 @@ window.addEventListener('message', async (event) => {
|
||||
window.watchItems[event.data.item_uid].push(event.data.appInstanceID);
|
||||
}
|
||||
//--------------------------------------------------------
|
||||
// launchApp
|
||||
//--------------------------------------------------------
|
||||
else if(event.data.msg === 'launchApp'){
|
||||
// TODO: Determine if the app is allowed to launch child apps? We may want to limit this to prevent abuse.
|
||||
// remember app for launch callback later
|
||||
const child_instance_id = window.uuidv4();
|
||||
window.child_launch_callbacks[child_instance_id] = {
|
||||
parent_instance_id: event.data.appInstanceID,
|
||||
launch_msg_id: msg_id,
|
||||
};
|
||||
// launch child app
|
||||
launch_app({
|
||||
name: event.data.app_name ?? app_name,
|
||||
args: event.data.args ?? {},
|
||||
parent_instance_id: event.data.appInstanceID,
|
||||
uuid: child_instance_id,
|
||||
});
|
||||
}
|
||||
//--------------------------------------------------------
|
||||
// readAppDataFile
|
||||
//--------------------------------------------------------
|
||||
else if(event.data.msg === 'readAppDataFile' && event.data.path !== undefined){
|
||||
|
@ -986,7 +986,7 @@ async function UIDesktop(options){
|
||||
|
||||
// 'show desktop'
|
||||
if(window.is_fullpage_mode){
|
||||
ht += `<a href="/" class="show-desktop-btn toolbar-btn antialiased" target="_blank" title="Show Desktop">Show Desktop <img src="${window.icons['launch-white.svg']}" style="width: 15px; height: 15px; margin-left: 5px;"></a>`;
|
||||
ht += `<a href="/" class="show-desktop-btn toolbar-btn antialiased" target="_blank" title="Show Desktop">Show Desktop <img src="${window.icons['launch-white.svg']}" style="width: 10px; height: 10px; margin-left: 5px;"></a>`;
|
||||
}
|
||||
|
||||
// refer
|
||||
@ -994,6 +994,9 @@ async function UIDesktop(options){
|
||||
ht += `<div class="toolbar-btn refer-btn" title="Refer" style="background-image:url(${window.icons['gift.svg']});"></div>`;
|
||||
}
|
||||
|
||||
// github
|
||||
ht += `<a href="https://github.com/HeyPuter/puter" target="_blank" class="toolbar-btn" title="GitHub" style="background-image:url(${window.icons['logo-github-white.svg']});"></a>`;
|
||||
|
||||
// do not show the fullscreen button on mobile devices since it's broken
|
||||
if(!isMobile.phone){
|
||||
// fullscreen button
|
||||
@ -1019,6 +1022,29 @@ async function UIDesktop(options){
|
||||
// adjust window container to take into account the toolbar height
|
||||
$('.window-container').css('top', window.toolbar_height);
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Determine if an app was launched from URL
|
||||
// i.e. https://puter.com/app/<app_name>
|
||||
//--------------------------------------------------------------------------------------
|
||||
if(window.url_paths[0]?.toLocaleLowerCase() === 'app' && window.url_paths[1]){
|
||||
window.app_launched_from_url = window.url_paths[1];
|
||||
// get app metadata
|
||||
try{
|
||||
window.app_launched_from_url = await puter.apps.get(window.url_paths[1])
|
||||
window.is_fullpage_mode = window.app_launched_from_url.metadata?.fullpage_on_landing ?? false;
|
||||
}catch(e){
|
||||
console.error(e);
|
||||
}
|
||||
|
||||
// get query params, any param that doesn't start with 'puter.' will be passed to the app
|
||||
window.app_query_params = {};
|
||||
for (let [key, value] of window.url_query_params) {
|
||||
if(!key.startsWith('puter.'))
|
||||
window.app_query_params[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------
|
||||
// Run apps from insta-login URL
|
||||
// ---------------------------------------------
|
||||
|
6
src/gui/src/icons/logo-github-white.svg
Normal file
6
src/gui/src/icons/logo-github-white.svg
Normal file
@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="16px" height="16px" viewBox="0 0 16 16"><g transform="translate(0, 0)"><path fill-rule="evenodd" clip-rule="evenodd" fill="#ffffff" d="M8,0.2c-4.4,0-8,3.6-8,8c0,3.5,2.3,6.5,5.5,7.6
|
||||
C5.9,15.9,6,15.6,6,15.4c0-0.2,0-0.7,0-1.4C3.8,14.5,3.3,13,3.3,13c-0.4-0.9-0.9-1.2-0.9-1.2c-0.7-0.5,0.1-0.5,0.1-0.5
|
||||
c0.8,0.1,1.2,0.8,1.2,0.8C4.4,13.4,5.6,13,6,12.8c0.1-0.5,0.3-0.9,0.5-1.1c-1.8-0.2-3.6-0.9-3.6-4c0-0.9,0.3-1.6,0.8-2.1
|
||||
c-0.1-0.2-0.4-1,0.1-2.1c0,0,0.7-0.2,2.2,0.8c0.6-0.2,1.3-0.3,2-0.3c0.7,0,1.4,0.1,2,0.3c1.5-1,2.2-0.8,2.2-0.8
|
||||
c0.4,1.1,0.2,1.9,0.1,2.1c0.5,0.6,0.8,1.3,0.8,2.1c0,3.1-1.9,3.7-3.7,3.9C9.7,12,10,12.5,10,13.2c0,1.1,0,1.9,0,2.2
|
||||
c0,0.2,0.1,0.5,0.6,0.4c3.2-1.1,5.5-4.1,5.5-7.6C16,3.8,12.4,0.2,8,0.2z"></path></g></svg>
|
After Width: | Height: | Size: 832 B |
@ -61,7 +61,7 @@ window.gui = async function(options){
|
||||
// DEV: Load the initgui.js file if we are in development mode
|
||||
if(!window.gui_env || window.gui_env === "dev"){
|
||||
await window.loadScript('/sdk/puter.dev.js');
|
||||
await window.loadScript(`${options.asset_dir}/initgui.js`, {isModule: true});
|
||||
// await window.loadScript(`${options.asset_dir}/initgui.js`, {isModule: true});
|
||||
}
|
||||
|
||||
// PROD: load the minified bundles if we are in production mode
|
||||
@ -71,7 +71,6 @@ window.gui = async function(options){
|
||||
await window.loadScript('https://js.puter.com/v2/');
|
||||
// Load the minified bundles
|
||||
await window.loadCSS('/dist/bundle.min.css');
|
||||
await window.loadScript('/dist/bundle.min.js');
|
||||
}
|
||||
|
||||
// 🚀 Launch the GUI 🚀
|
||||
|
@ -46,6 +46,8 @@ import update_mouse_position from './helpers/update_mouse_position.js';
|
||||
import { LaunchOnInitService } from './services/LaunchOnInitService.js';
|
||||
import item_icon from './helpers/item_icon.js';
|
||||
import { AntiCSRFService } from './services/AntiCSRFService.js';
|
||||
import { IPCService } from './services/IPCService.js';
|
||||
import { ExecService } from './services/ExecService.js';
|
||||
|
||||
const launch_services = async function (options) {
|
||||
// === Services Data Structures ===
|
||||
@ -75,6 +77,8 @@ const launch_services = async function (options) {
|
||||
globalThis.service_script_api_promise.resolve(service_script_api);
|
||||
|
||||
// === Builtin Services ===
|
||||
register('ipc', new IPCService());
|
||||
register('exec', new ExecService());
|
||||
register('broadcast', new BroadcastService());
|
||||
register('theme', new ThemeService());
|
||||
register('process', new ProcessService());
|
||||
@ -188,30 +192,7 @@ window.initgui = async function(options){
|
||||
// will hold the result of the whoami API call
|
||||
let whoami;
|
||||
|
||||
const url_paths = window.location.pathname.split('/').filter(element => element);
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Determine if an app was launched from URL
|
||||
// i.e. https://puter.com/app/<app_name>
|
||||
//--------------------------------------------------------------------------------------
|
||||
if(url_paths[0]?.toLocaleLowerCase() === 'app' && url_paths[1]){
|
||||
window.app_launched_from_url = url_paths[1];
|
||||
|
||||
// get app metadata
|
||||
try{
|
||||
window.app_launched_from_url = await puter.apps.get(window.app_launched_from_url)
|
||||
window.is_fullpage_mode = window.app_launched_from_url.metadata?.fullpage_on_landing ?? false;
|
||||
}catch(e){
|
||||
console.error(e);
|
||||
}
|
||||
|
||||
// get query params, any param that doesn't start with 'puter.' will be passed to the app
|
||||
window.app_query_params = {};
|
||||
for (let [key, value] of window.url_query_params) {
|
||||
if(!key.startsWith('puter.'))
|
||||
window.app_query_params[key] = value;
|
||||
}
|
||||
}
|
||||
window.url_paths = window.location.pathname.split('/').filter(element => element);
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Extract 'action' from URL
|
||||
@ -235,7 +216,6 @@ window.initgui = async function(options){
|
||||
window.is_fullpage_mode = true;
|
||||
}
|
||||
|
||||
|
||||
// Launch services before any UI is rendered
|
||||
await launch_services(options);
|
||||
|
||||
|
33
src/gui/src/services/ExecService.js
Normal file
33
src/gui/src/services/ExecService.js
Normal file
@ -0,0 +1,33 @@
|
||||
import { Service } from "../definitions.js";
|
||||
import launch_app from "../helpers/launch_app.js";
|
||||
|
||||
export class ExecService extends Service {
|
||||
static description = `
|
||||
Manages instances of apps on the Puter desktop.
|
||||
`
|
||||
|
||||
async _init ({ services }) {
|
||||
const svc_ipc = services.get('ipc');
|
||||
svc_ipc.register_ipc_handler('launchApp', {
|
||||
handler: this.launchApp.bind(this),
|
||||
});
|
||||
}
|
||||
|
||||
// This method is exposed to apps via IPCService.
|
||||
launchApp ({ app_name, args }, { ipc_context, msg_id } = {}) {
|
||||
// This mechanism will be replated with xdrpc soon
|
||||
const child_instance_id = window.uuidv4();
|
||||
window.child_launch_callbacks[child_instance_id] = {
|
||||
parent_instance_id: event.data.appInstanceID,
|
||||
launch_msg_id: msg_id,
|
||||
};
|
||||
|
||||
// The "body" of this method is in a separate file
|
||||
launch_app({
|
||||
name: app_name,
|
||||
args: args ?? {},
|
||||
parent_instance_id: ipc_context?.appInstanceId,
|
||||
uuid: child_instance_id,
|
||||
});
|
||||
}
|
||||
}
|
15
src/gui/src/services/IPCService.js
Normal file
15
src/gui/src/services/IPCService.js
Normal file
@ -0,0 +1,15 @@
|
||||
import { Service } from "../definitions.js";
|
||||
|
||||
export class IPCService extends Service {
|
||||
static description = `
|
||||
Allows other services to expose methods to apps.
|
||||
`
|
||||
|
||||
async _init () {
|
||||
//
|
||||
}
|
||||
|
||||
register_ipc_handler (name, spec) {
|
||||
window.ipc_handlers[name] = spec;
|
||||
}
|
||||
}
|
@ -20,10 +20,12 @@ import { encode } from 'html-entities';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import webpack from 'webpack';
|
||||
import webpack_config from './webpack.config.cjs';
|
||||
import CleanCSS from 'clean-css';
|
||||
import uglifyjs from 'uglify-js';
|
||||
import { lib_paths, css_paths, js_paths } from './src/static-assets.js';
|
||||
import { fileURLToPath } from 'url';
|
||||
import BaseConfig from './webpack/BaseConfig.cjs';
|
||||
|
||||
// Polyfill __dirname, which doesn't exist in modules mode
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
@ -128,14 +130,11 @@ async function build(options){
|
||||
main_array.push(path.join(__dirname, 'src', js_paths[i]));
|
||||
}
|
||||
webpack({
|
||||
...BaseConfig({
|
||||
...options,
|
||||
env: 'prod',
|
||||
}),
|
||||
mode: 'production',
|
||||
entry: {
|
||||
main: main_array,
|
||||
},
|
||||
output: {
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
filename: '[name].js',
|
||||
},
|
||||
optimization: {
|
||||
minimize: true,
|
||||
},
|
||||
@ -147,9 +146,9 @@ async function build(options){
|
||||
if(options?.verbose)
|
||||
console.log(stats.toString());
|
||||
// write to ./dist/bundle.min.js
|
||||
fs.writeFileSync(path.join(__dirname, 'dist', 'bundle.min.js'), icons + '\n\n\n' + js + '\n\n\n' + fs.readFileSync(path.join(__dirname, 'dist', 'main.js')));
|
||||
// fs.writeFileSync(path.join(__dirname, 'dist', 'bundle.min.js'), fs.readFileSync(path.join(__dirname, 'dist', 'main.js')));
|
||||
// remove ./dist/main.js
|
||||
fs.unlinkSync(path.join(__dirname, 'dist', 'main.js'));
|
||||
// fs.unlinkSync(path.join(__dirname, 'dist', 'main.js'));
|
||||
});
|
||||
|
||||
// Copy index.js to dist/gui.js
|
||||
|
8
src/gui/webpack.config.cjs
Normal file
8
src/gui/webpack.config.cjs
Normal file
@ -0,0 +1,8 @@
|
||||
const BaseConfig = require('./webpack/BaseConfig.cjs');
|
||||
|
||||
module.exports = {
|
||||
...BaseConfig({ env: 'dev' }),
|
||||
optimization: {
|
||||
minimize: false
|
||||
},
|
||||
};
|
27
src/gui/webpack/BaseConfig.cjs
Normal file
27
src/gui/webpack/BaseConfig.cjs
Normal file
@ -0,0 +1,27 @@
|
||||
const path = require('path');
|
||||
const EmitPlugin = require('./EmitPlugin.cjs');
|
||||
module.exports = (options = {}) => {
|
||||
const config = {};
|
||||
config.entry = [
|
||||
'./src/init_sync.js',
|
||||
'./src/init_async.js',
|
||||
'./src/initgui.js',
|
||||
'./src/helpers.js',
|
||||
'./src/IPC.js',
|
||||
'./src/globals.js',
|
||||
'./src/i18n/i18n.js',
|
||||
'./src/keyboard.js',
|
||||
'./src/index.js',
|
||||
];
|
||||
config.output = {
|
||||
path: path.resolve(__dirname, '../dist'),
|
||||
filename: 'bundle.min.js',
|
||||
};
|
||||
config.plugins = [
|
||||
EmitPlugin({
|
||||
options,
|
||||
dir: path.join(__dirname, '../src/icons'),
|
||||
}),
|
||||
];
|
||||
return config;
|
||||
};
|
78
src/gui/webpack/EmitPlugin.cjs
Normal file
78
src/gui/webpack/EmitPlugin.cjs
Normal file
@ -0,0 +1,78 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const uglifyjs = require('uglify-js');
|
||||
|
||||
module.exports = ({ dir, options }) => function () {
|
||||
const compiler = this;
|
||||
compiler.hooks.emit.tapAsync('EmitPlugin', async (compilation, callback) => {
|
||||
let prefix_text = '';
|
||||
prefix_text += `window.gui_env="${options.env}";\n`;
|
||||
|
||||
// -----------------------------------------------
|
||||
// Combine all images into a single js file
|
||||
// -----------------------------------------------
|
||||
{
|
||||
let icons = 'window.icons = [];\n';
|
||||
fs.readdirSync(dir).forEach(file => {
|
||||
// skip dotfiles
|
||||
if (file.startsWith('.'))
|
||||
return;
|
||||
// load image
|
||||
let buff = new Buffer.from(fs.readFileSync(dir + '/' + file));
|
||||
// convert to base64
|
||||
let base64data = buff.toString('base64');
|
||||
// add to `window.icons`
|
||||
if (file.endsWith('.png'))
|
||||
icons += `window.icons['${file}'] = "data:image/png;base64,${base64data}";\n`;
|
||||
else if (file.endsWith('.svg'))
|
||||
icons += `window.icons['${file}'] = "data:image/svg+xml;base64,${base64data}";\n`;
|
||||
});
|
||||
prefix_text += icons + '\n';
|
||||
}
|
||||
|
||||
// -----------------------------------------------
|
||||
// Concat/merge the JS libraries and save them to ./dist/libs.js
|
||||
// -----------------------------------------------
|
||||
{
|
||||
const lib_paths = require('./libPaths.cjs');
|
||||
let js = '';
|
||||
for(let i = 0; i < lib_paths.length; i++){
|
||||
const file = path.join(__dirname, '../src/lib/', lib_paths[i]);
|
||||
// js
|
||||
if(file.endsWith('.js') && !file.endsWith('.min.js')){
|
||||
let minified_code = await uglifyjs.minify(fs.readFileSync(file).toString(), {mangle: false});
|
||||
if(minified_code && minified_code.code){
|
||||
js += minified_code.code;
|
||||
if(options?.verbose)
|
||||
console.log('minified: ', file);
|
||||
}
|
||||
}else{
|
||||
js += fs.readFileSync(file);
|
||||
if(options?.verbose)
|
||||
console.log('skipped minification: ', file);
|
||||
}
|
||||
|
||||
js += '\n\n\n';
|
||||
}
|
||||
prefix_text += js;
|
||||
}
|
||||
|
||||
// -----------------------------------------------
|
||||
// Webpack understands this code better than I do
|
||||
// -----------------------------------------------
|
||||
Object.keys(compilation.assets).forEach((assetName) => {
|
||||
if (assetName.endsWith('.js')) {
|
||||
const asset = compilation.assets[assetName];
|
||||
const originalSource = asset.source();
|
||||
const newSource = `${prefix_text}\n${originalSource}`;
|
||||
compilation.assets[assetName] = {
|
||||
source: () => newSource,
|
||||
size: () => newSource.length,
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
console.log('END');
|
||||
callback();
|
||||
});
|
||||
};
|
15
src/gui/webpack/libPaths.cjs
Normal file
15
src/gui/webpack/libPaths.cjs
Normal file
@ -0,0 +1,15 @@
|
||||
module.exports = [
|
||||
"jquery-3.6.1/jquery-3.6.1.min.js",
|
||||
"viselect.min.js",
|
||||
"FileSaver.min.js",
|
||||
"socket.io/socket.io.min.js",
|
||||
"qrcode.min.js",
|
||||
"jquery-ui-1.13.2/jquery-ui.min.js",
|
||||
"lodash@4.17.21.min.js",
|
||||
"jquery.dragster.js",
|
||||
"html-entities.js",
|
||||
"timeago.min.js",
|
||||
"iro.min.js",
|
||||
"isMobile.min.js",
|
||||
"jszip-3.10.1.min.js"
|
||||
];
|
@ -20,7 +20,7 @@ import fs from 'fs';
|
||||
import path_ from 'path';
|
||||
|
||||
import modeString from 'fs-mode-to-string';
|
||||
import { ErrorCodes, PosixError } from '@heyputer/puter-js-common/src/PosixError.js';
|
||||
import { ErrorCodes, PosixError } from '@heyputer/putility/src/PosixError.js';
|
||||
|
||||
// DRY: Almost the same as puter/filesystem.js
|
||||
function wrapAPIs(apis) {
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { ErrorCodes, PosixError } from '@heyputer/puter-js-common/src/PosixError.js';
|
||||
import { ErrorCodes, PosixError } from '@heyputer/putility/src/PosixError.js';
|
||||
|
||||
// DRY: Almost the same as node/filesystem.js
|
||||
function wrapAPIs(apis) {
|
||||
|
@ -16,7 +16,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { ErrorCodes, ErrorMetadata, errorFromIntegerCode } from '@heyputer/puter-js-common/src/PosixError.js';
|
||||
import { ErrorCodes, ErrorMetadata, errorFromIntegerCode } from '@heyputer/putility/src/PosixError.js';
|
||||
import { Exit } from './coreutil_lib/exit.js';
|
||||
|
||||
const maxErrorNameLength = Object.keys(ErrorCodes)
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user