tsoft-cli 1.2.0 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -0
- package/README.md +103 -7
- package/bin/index.js +45 -45
- package/package.json +3 -2
- package/src/client-credentials.js +27 -3
- package/src/commands/create.js +63 -30
- package/src/commands/start.js +132 -78
- package/src/commands/sync.js +80 -0
- package/src/file-manager.js +31 -0
- package/src/request.js +22 -1
- package/src/theme-manager.js +3 -0
- package/src/tsoft.js +6 -2
package/CHANGELOG.md
CHANGED
|
@@ -13,3 +13,35 @@
|
|
|
13
13
|
|
|
14
14
|
### Fixed
|
|
15
15
|
- Birkaç hata düzeltildi ve genel kod kalitesi iyileştirildi.
|
|
16
|
+
|
|
17
|
+
# Changelog
|
|
18
|
+
|
|
19
|
+
## [1.2.1] - 2024-06-13
|
|
20
|
+
### Added
|
|
21
|
+
- T-Soft CLI'de yeni bir site oluşturma ve geçerliliğini kontrol etme özelliği eklendi.
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
- `start.js` ve `create.js` dosyalarında refaktörizasyon yapıldı.
|
|
25
|
+
- T-Soft CLI ana menüsü, site ve tema seçimlerinin interaktif hale getirilmesi amacıyla güncellendi.
|
|
26
|
+
- Tüm metinler Türkçeleştirildi ve kullanıcıya daha açıklayıcı mesajlar sağlandı.
|
|
27
|
+
|
|
28
|
+
### Fixed
|
|
29
|
+
- Geliştirme ortamı başlatıldığında programın beklenmedik şekilde kapanmasına sebep olan hata giderildi.
|
|
30
|
+
- T-Soft CLI'nın `start.js` dosyasında initialize fonksiyonunun doğru şekilde çalışmaması sorunu çözüldü.
|
|
31
|
+
|
|
32
|
+
# Changelog
|
|
33
|
+
|
|
34
|
+
## [1.2.2] - 2024-06-14
|
|
35
|
+
### Added
|
|
36
|
+
- Kurtarma anahtarı ile tema senkronizasyonu yapan `syncTheme` fonksiyonu eklendi.
|
|
37
|
+
- `syncTheme` fonksiyonu zip dosyasını indirip açma işlemi gerçekleştiriyor.
|
|
38
|
+
- Tema bilgilerini içeren `.theme` dosyası oluşturma ve `theme.env` dosyası yaratma işlemleri eklendi.
|
|
39
|
+
- Kullanıcı komut satırı etkileşimleri için `enquirer` kütüphanesi kullanıldı.
|
|
40
|
+
|
|
41
|
+
### Changed
|
|
42
|
+
- `unzipFile` fonksiyonu eklendi, zip dosyalarını açmak için kullanılıyor.
|
|
43
|
+
- `sync.js` dosyasında kullanıcıdan kurtarma anahtarı alınarak gerekli işlemlerin yapılması sağlandı.
|
|
44
|
+
|
|
45
|
+
### Fixed
|
|
46
|
+
- Zip dosyasının indirildikten sonra otomatik olarak silinmesi sağlandı.
|
|
47
|
+
- `sync.js` dosyasında oluşan hatalar giderildi ve kod kalitesi iyileştirildi.
|
package/README.md
CHANGED
|
@@ -1,10 +1,106 @@
|
|
|
1
|
-
|
|
1
|
+
T-Soft CLI Kullanım Kılavuzu
|
|
2
|
+
============================
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
4
|
+
Açıklama
|
|
5
|
+
--------
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npm install -g tsoft-cli
|
|
9
|
-
```
|
|
7
|
+
T-Soft CLI, T-Soft için tema geliştirmek isteyen geliştiriciler için özel olarak hazırlanmış bir komut satırı arayüzüdür. Bu araç ile yeni temalar oluşturabilir, mevcut temaları düzenleyebilir ve geliştirme ortamınızı kolaylıkla yönetebilirsiniz.
|
|
10
8
|
|
|
9
|
+
Kurulum
|
|
10
|
+
-------
|
|
11
|
+
|
|
12
|
+
CLI aracını kullanmaya başlamadan önce, aşağıdaki adımları izleyerek T-Soft CLI'yı kurmanız gerekmektedir:
|
|
13
|
+
|
|
14
|
+
### NPM ile Kurulum
|
|
15
|
+
|
|
16
|
+
T-Soft CLI'yı global olarak kurmak için aşağıdaki komutu çalıştırın:
|
|
17
|
+
|
|
18
|
+
npm install -g tsoft-cli
|
|
19
|
+
|
|
20
|
+
Kullanım
|
|
21
|
+
--------
|
|
22
|
+
|
|
23
|
+
CLI arayüzünü çalıştırmak için terminale `tsoft-cli` yazmanız yeterlidir:
|
|
24
|
+
|
|
25
|
+
tsoft-cli
|
|
26
|
+
|
|
27
|
+
### Ana Menü
|
|
28
|
+
|
|
29
|
+
CLI başlatıldığında aşağıdaki seçeneklerle ana menü görünür:
|
|
30
|
+
|
|
31
|
+
* Yeni bir tema oluştur
|
|
32
|
+
* Geliştirme ortamını başlat
|
|
33
|
+
* Çıkış
|
|
34
|
+
|
|
35
|
+
### Yeni Bir Tema Oluşturma
|
|
36
|
+
|
|
37
|
+
Yeni bir tema oluşturmak için aşağıdaki adımları izleyin:
|
|
38
|
+
|
|
39
|
+
1. **Yeni Tema Oluşturma Seçeneğini Seçin**: Ana menüden `Yeni bir tema oluştur` seçeneğini seçin.
|
|
40
|
+
2. **Site Adı Seçimi**:
|
|
41
|
+
* Mevcut sitelerden birini seçin veya `Yeni bir site oluştur` seçeneğini seçin.
|
|
42
|
+
* Yeni bir site oluşturmak istiyorsanız, site adını girin. Bu ad, geçerliliği kontrol edilecektir.
|
|
43
|
+
3. **Tema Detayları**:
|
|
44
|
+
* Tema adı, yazar adı (isteğe bağlı) ve versiyon numarasını girin.
|
|
45
|
+
4. **Tema Oluşturma**: Tema başarıyla oluşturulduktan sonra otomatik olarak geliştirme ortamına geçilir.
|
|
46
|
+
|
|
47
|
+
### Geliştirme Ortamını Başlatma
|
|
48
|
+
|
|
49
|
+
Mevcut bir temayı düzenlemek veya geliştirmek için geliştirme ortamını başlatabilirsiniz:
|
|
50
|
+
|
|
51
|
+
1. **Geliştirme Ortamını Başlatma Seçeneğini Seçin**: Ana menüden `Geliştirme ortamını başlat` seçeneğini seçin.
|
|
52
|
+
2. **Site ve Tema Seçimi**:
|
|
53
|
+
* Mevcut sitelerden birini seçin.
|
|
54
|
+
* Seçilen sitedeki temalardan birini seçin.
|
|
55
|
+
3. **Geliştirme Ortamı**: Seçilen tema için geliştirme ortamı başlatılır ve dosya değişiklikleri izlenir.
|
|
56
|
+
|
|
57
|
+
### Geliştirme Ortamında Kullanılabilir Komutlar
|
|
58
|
+
|
|
59
|
+
Geliştirme ortamında aşağıdaki komutları kullanabilirsiniz:
|
|
60
|
+
|
|
61
|
+
* `q`: Dosya izlemeyi sonlandırır.
|
|
62
|
+
* `u`: Temayı günceller.
|
|
63
|
+
* `s`: Tüm dosyaları kaydeder.
|
|
64
|
+
* `e`: `.theme` dosyasını düzenler.
|
|
65
|
+
* `o`: Tema dizinini açar.
|
|
66
|
+
|
|
67
|
+
Proje Yapısı
|
|
68
|
+
------------
|
|
69
|
+
|
|
70
|
+
Projenizin dosya yapısı şu şekildedir:
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
tsoft-cli/
|
|
74
|
+
├── bin/
|
|
75
|
+
│ └── index.js
|
|
76
|
+
├── src/
|
|
77
|
+
│ ├── commands/
|
|
78
|
+
│ │ ├── create.js
|
|
79
|
+
│ │ └── start.js
|
|
80
|
+
│ ├── tsoft/
|
|
81
|
+
│ │ └── themeManager.js
|
|
82
|
+
│ ├── utils.js
|
|
83
|
+
│ └── constants.js
|
|
84
|
+
├── CHANGELOG.md
|
|
85
|
+
├── package.json
|
|
86
|
+
└── README.md
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
### Dosya ve Klasör Açıklamaları
|
|
90
|
+
|
|
91
|
+
* `bin/index.js`: Ana CLI giriş noktasıdır. Kullanıcı komutları burada işlenir ve ilgili komut dosyaları çalıştırılır.
|
|
92
|
+
* `src/commands/create.js`: Yeni bir tema oluşturmak için kullanılan komut dosyasıdır. Kullanıcıdan site ve tema adı alır ve temayı oluşturur.
|
|
93
|
+
* `src/commands/start.js`: Geliştirme ortamını başlatmak için kullanılan komut dosyasıdır. Dosya değişikliklerini izler ve temayı günceller.
|
|
94
|
+
* `src/tsoft/themeManager.js`: Tema yönetimi işlemlerini gerçekleştiren sınıftır. Temanın başlatılması, geçerliliğinin kontrol edilmesi ve ortamın oluşturulması işlemlerini yapar.
|
|
95
|
+
* `src/utils.js`: Yardımcı fonksiyonlar içerir.
|
|
96
|
+
* `src/constants.js`: Sabit değerleri içerir.
|
|
97
|
+
|
|
98
|
+
Katkıda Bulunma
|
|
99
|
+
---------------
|
|
100
|
+
|
|
101
|
+
Proje açık kaynaklıdır ve katkılara açıktır. Katkıda bulunmak isterseniz, lütfen bir pull request gönderin veya bir issue açın.
|
|
102
|
+
|
|
103
|
+
Lisans
|
|
104
|
+
------
|
|
105
|
+
|
|
106
|
+
Bu proje ISC lisansı altında lisanslanmıştır. Daha fazla bilgi için `LICENSE` dosyasına bakabilirsiniz.
|
package/bin/index.js
CHANGED
|
@@ -1,74 +1,74 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
const {
|
|
4
|
-
const {
|
|
5
|
-
const {
|
|
6
|
-
const {
|
|
3
|
+
const {Select} = require('enquirer');
|
|
4
|
+
const {start} = require('../src/commands/start');
|
|
5
|
+
const {syncTheme} = require('../src/commands/sync'); // Yeni komut dosyasını ekle
|
|
6
|
+
const {createTheme} = require('../src/commands/create');
|
|
7
|
+
const {clearScreen, displayAsciiArt} = require('../src/utils');
|
|
7
8
|
const fs = require('fs');
|
|
8
9
|
const path = require('path');
|
|
9
10
|
|
|
11
|
+
async function getDirectories(source) {
|
|
12
|
+
return fs.readdirSync(source).filter(file => {
|
|
13
|
+
return file.charAt(0) !== '.' && !['node_modules', 'build', 'dist'].includes(file);
|
|
14
|
+
}).filter(file => fs.statSync(path.join(source, file)).isDirectory());
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async function selectFromChoices(message, choices) {
|
|
18
|
+
const prompt = new Select({
|
|
19
|
+
name: 'selection',
|
|
20
|
+
message: message,
|
|
21
|
+
choices: choices
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
return await prompt.run();
|
|
25
|
+
}
|
|
26
|
+
|
|
10
27
|
async function selectSiteAndTheme() {
|
|
11
28
|
const cwd = process.cwd();
|
|
12
|
-
const sites =
|
|
13
|
-
return file.charAt(0) !== '.' && !['node_modules', 'build', 'dist'].includes(file);
|
|
14
|
-
}).filter(file => fs.statSync(path.join(cwd, file)).isDirectory());
|
|
29
|
+
const sites = await getDirectories(cwd);
|
|
15
30
|
|
|
16
31
|
if (sites.length === 0) {
|
|
17
32
|
console.error('Mevcut dizinde site bulunamadı.');
|
|
18
33
|
return null;
|
|
19
34
|
}
|
|
20
35
|
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
message: 'Bir site seçin:',
|
|
24
|
-
choices: sites
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
const selectedSite = await sitePrompt.run();
|
|
28
|
-
|
|
29
|
-
const themes = fs.readdirSync(path.join(cwd, selectedSite)).filter(file => {
|
|
30
|
-
return fs.statSync(path.join(cwd, selectedSite, file)).isDirectory();
|
|
31
|
-
});
|
|
36
|
+
const selectedSite = await selectFromChoices('Bir site seçin:', sites);
|
|
37
|
+
const themes = await getDirectories(path.join(cwd, selectedSite));
|
|
32
38
|
|
|
33
39
|
if (themes.length === 0) {
|
|
34
40
|
console.error('Seçilen site dizininde tema bulunamadı.');
|
|
35
41
|
return null;
|
|
36
42
|
}
|
|
37
43
|
|
|
38
|
-
const
|
|
39
|
-
name: 'theme',
|
|
40
|
-
message: 'Bir tema seçin:',
|
|
41
|
-
choices: themes
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
const selectedTheme = await themePrompt.run();
|
|
44
|
+
const selectedTheme = await selectFromChoices('Bir tema seçin:', themes);
|
|
45
45
|
|
|
46
|
-
return {
|
|
46
|
+
return {siteName: selectedSite, themeName: selectedTheme};
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
async function showMainMenu() {
|
|
50
50
|
clearScreen();
|
|
51
|
-
|
|
52
51
|
await displayAsciiArt();
|
|
53
52
|
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
53
|
+
const commandChoices = ['Yeni bir tema oluştur', 'Geliştirme ortamını başlat', 'Uzak sunucudan dosyaları indir', 'Çıkış'];
|
|
54
|
+
const selectedCommand = await selectFromChoices('Bir komut seçin', commandChoices);
|
|
55
|
+
|
|
56
|
+
switch (selectedCommand) {
|
|
57
|
+
case 'Yeni bir tema oluştur':
|
|
58
|
+
await createTheme();
|
|
59
|
+
break;
|
|
60
|
+
case 'Geliştirme ortamını başlat':
|
|
61
|
+
const selection = await selectSiteAndTheme();
|
|
62
|
+
if (selection) {
|
|
63
|
+
await start(selection.siteName, selection.themeName);
|
|
64
|
+
}
|
|
65
|
+
break;
|
|
66
|
+
case 'Uzak sunucudan dosyaları indir':
|
|
67
|
+
await syncTheme();
|
|
68
|
+
break;
|
|
69
|
+
case 'Çıkış':
|
|
70
|
+
console.log('Programdan çıkılıyor. Hoşça kalın!');
|
|
71
|
+
process.exit(0);
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tsoft-cli",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.2",
|
|
4
4
|
"description": "A theme development cli for developers who want to create themes for T-Soft.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
"commander": "^12.1.0",
|
|
19
19
|
"enquirer": "^2.4.1",
|
|
20
20
|
"figlet": "^1.7.0",
|
|
21
|
-
"fs": "^0.0.1-security"
|
|
21
|
+
"fs": "^0.0.1-security",
|
|
22
|
+
"unzipper": "^0.12.1"
|
|
22
23
|
},
|
|
23
24
|
"type": "commonjs",
|
|
24
25
|
"devDependencies": {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const buildPostRequest = require('./request');
|
|
1
|
+
const {buildPostRequest} = require('./request');
|
|
2
2
|
|
|
3
3
|
class ClientCredentials {
|
|
4
4
|
site;
|
|
@@ -29,6 +29,11 @@ class ClientCredentials {
|
|
|
29
29
|
return this;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
setClientId(clientId) {
|
|
33
|
+
this.clientId = clientId;
|
|
34
|
+
return this;
|
|
35
|
+
}
|
|
36
|
+
|
|
32
37
|
async register(CLIENT_UUID, clientConfiguration = {}) {
|
|
33
38
|
|
|
34
39
|
const uri = "api/v3/admin/auth/auth-application";
|
|
@@ -37,7 +42,7 @@ class ClientCredentials {
|
|
|
37
42
|
'Content-Type': 'application/json', 'Accept': 'application/json',
|
|
38
43
|
}, body: JSON.stringify({
|
|
39
44
|
uuid: CLIENT_UUID, configuration: {
|
|
40
|
-
|
|
45
|
+
name: clientConfiguration.name,
|
|
41
46
|
author: clientConfiguration.author,
|
|
42
47
|
version: clientConfiguration.version
|
|
43
48
|
}
|
|
@@ -55,14 +60,19 @@ class ClientCredentials {
|
|
|
55
60
|
|
|
56
61
|
async authorize() {
|
|
57
62
|
const uri = "api/v3/admin/auth/auth-application/authorize";
|
|
58
|
-
await this.buildPostRequest(uri, {
|
|
63
|
+
return await this.buildPostRequest(uri, {
|
|
59
64
|
body: JSON.stringify({
|
|
60
65
|
public_key: this.clientId, secret: this.clientSecret
|
|
61
66
|
})
|
|
62
67
|
}).then((result) => {
|
|
63
68
|
if (result.status === true) {
|
|
64
69
|
this.bearer = result.data.token.plainTextToken
|
|
70
|
+
return result;
|
|
65
71
|
}
|
|
72
|
+
return false;
|
|
73
|
+
}).catch((error) => {
|
|
74
|
+
console.error('Hata:', error.message);
|
|
75
|
+
return false;
|
|
66
76
|
});
|
|
67
77
|
|
|
68
78
|
}
|
|
@@ -83,6 +93,20 @@ class ClientCredentials {
|
|
|
83
93
|
});
|
|
84
94
|
return response.message === 'ok';
|
|
85
95
|
}
|
|
96
|
+
|
|
97
|
+
async recovery(token) {
|
|
98
|
+
const uri = 'api/v3/admin/auth/auth-application/recovery/' + token;
|
|
99
|
+
|
|
100
|
+
const response = await buildPostRequest(this.site, uri);
|
|
101
|
+
|
|
102
|
+
if (response.status) {
|
|
103
|
+
return {
|
|
104
|
+
secret: response.data.secret,
|
|
105
|
+
public_key: response.data.public_key
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
}
|
|
86
110
|
}
|
|
87
111
|
|
|
88
112
|
module.exports = ClientCredentials;
|
package/src/commands/create.js
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
|
-
const {
|
|
3
|
+
const {Select, Input} = require('enquirer');
|
|
4
4
|
const {slugify} = require('../utils');
|
|
5
|
-
const {
|
|
5
|
+
const {start} = require('./start');
|
|
6
6
|
const ThemeManager = require('../theme-manager');
|
|
7
7
|
|
|
8
|
-
async function
|
|
8
|
+
async function getSites() {
|
|
9
9
|
const cwd = process.cwd();
|
|
10
|
-
|
|
10
|
+
return fs.readdirSync(cwd).filter(file => {
|
|
11
11
|
return file.charAt(0) !== '.' && !['node_modules', 'build', 'dist'].includes(file);
|
|
12
12
|
}).filter(file => fs.statSync(path.join(cwd, file)).isDirectory());
|
|
13
|
+
}
|
|
13
14
|
|
|
15
|
+
async function selectSite(sites) {
|
|
14
16
|
const siteChoices = [...sites, 'Yeni bir site oluştur'];
|
|
15
17
|
|
|
16
18
|
const sitePrompt = new Select({
|
|
@@ -21,30 +23,42 @@ async function createTheme() {
|
|
|
21
23
|
|
|
22
24
|
const selectedSite = await sitePrompt.run();
|
|
23
25
|
|
|
24
|
-
let siteName;
|
|
25
26
|
if (selectedSite === 'Yeni bir site oluştur') {
|
|
26
|
-
|
|
27
|
-
name: 'newSite',
|
|
28
|
-
message: 'Yeni site adı:'
|
|
29
|
-
});
|
|
30
|
-
siteName = await newSitePrompt.run();
|
|
31
|
-
|
|
32
|
-
const themeManager = new ThemeManager(siteName);
|
|
33
|
-
try {
|
|
34
|
-
const isValid = await themeManager.checkSiteValidity(siteName);
|
|
35
|
-
if (!isValid) {
|
|
36
|
-
console.error('Geçersiz site adı. Lütfen geçerli bir site adı girin.');
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
} catch (error) {
|
|
40
|
-
console.error('Site doğrulaması sırasında hata oluştu:', error.message);
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
|
|
27
|
+
return await createNewSite();
|
|
44
28
|
} else {
|
|
45
|
-
|
|
29
|
+
return selectedSite;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async function createNewSite() {
|
|
34
|
+
const newSitePrompt = new Input({
|
|
35
|
+
name: 'newSite',
|
|
36
|
+
message: 'Yeni site adı:'
|
|
37
|
+
});
|
|
38
|
+
const siteName = await newSitePrompt.run();
|
|
39
|
+
|
|
40
|
+
const themeManager = new ThemeManager(siteName);
|
|
41
|
+
const isValid = await validateSiteName(themeManager, siteName);
|
|
42
|
+
if (!isValid) return null;
|
|
43
|
+
|
|
44
|
+
return siteName;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async function validateSiteName(themeManager, siteName) {
|
|
48
|
+
try {
|
|
49
|
+
const isValid = await themeManager.checkSiteValidity(siteName);
|
|
50
|
+
if (!isValid) {
|
|
51
|
+
console.error('Geçersiz site adı. Lütfen geçerli bir site adı girin.');
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
return true;
|
|
55
|
+
} catch (error) {
|
|
56
|
+
console.error('Site doğrulaması sırasında hata oluştu:', error.message);
|
|
57
|
+
return false;
|
|
46
58
|
}
|
|
59
|
+
}
|
|
47
60
|
|
|
61
|
+
async function getThemeDetails() {
|
|
48
62
|
const themeNamePrompt = new Input({
|
|
49
63
|
name: 'themeName',
|
|
50
64
|
message: 'Tema adı:'
|
|
@@ -65,29 +79,48 @@ async function createTheme() {
|
|
|
65
79
|
const author = await authorPrompt.run();
|
|
66
80
|
const version = await versionPrompt.run();
|
|
67
81
|
|
|
68
|
-
|
|
82
|
+
return {themeName, author, version};
|
|
83
|
+
}
|
|
69
84
|
|
|
85
|
+
async function createThemeDirectory(siteName, themeNameSlug) {
|
|
86
|
+
const cwd = process.cwd();
|
|
70
87
|
const themePath = path.join(cwd, siteName, themeNameSlug);
|
|
71
88
|
|
|
72
89
|
if (!fs.existsSync(themePath)) {
|
|
73
|
-
fs.mkdirSync(themePath, {
|
|
90
|
+
fs.mkdirSync(themePath, {recursive: true});
|
|
74
91
|
}
|
|
75
92
|
|
|
93
|
+
return themePath;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async function saveThemeData(themePath, themeData) {
|
|
97
|
+
fs.writeFileSync(path.join(themePath, '.theme'), JSON.stringify(themeData, null, 2));
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
async function createTheme() {
|
|
101
|
+
const sites = await getSites();
|
|
102
|
+
const siteName = await selectSite(sites);
|
|
103
|
+
|
|
104
|
+
if (!siteName) return;
|
|
105
|
+
|
|
106
|
+
const {themeName, author, version} = await getThemeDetails();
|
|
107
|
+
const themeNameSlug = slugify(themeName);
|
|
108
|
+
const themePath = await createThemeDirectory(siteName, themeNameSlug);
|
|
109
|
+
|
|
76
110
|
const themeData = {
|
|
77
111
|
site: siteName,
|
|
78
|
-
|
|
112
|
+
name: themeName,
|
|
79
113
|
author: author,
|
|
80
114
|
version: version
|
|
81
115
|
};
|
|
82
116
|
|
|
83
|
-
|
|
117
|
+
await saveThemeData(themePath, themeData);
|
|
84
118
|
|
|
85
119
|
console.log(`Tema "${themeName}" başarıyla oluşturuldu.`);
|
|
86
120
|
|
|
87
|
-
// Doğrudan start fonksiyonuna geçiş yap
|
|
88
121
|
await start(siteName, themeNameSlug);
|
|
89
122
|
}
|
|
90
123
|
|
|
91
124
|
module.exports = {
|
|
92
|
-
createTheme
|
|
125
|
+
createTheme, createThemeDirectory, selectSite
|
|
93
126
|
};
|
package/src/commands/start.js
CHANGED
|
@@ -7,14 +7,13 @@ const Tsoft = require('../tsoft');
|
|
|
7
7
|
const constants = require('../constants');
|
|
8
8
|
const cliProgress = require('cli-progress');
|
|
9
9
|
const { Input } = require('enquirer');
|
|
10
|
-
const { displayAsciiArt, clearScreen, info
|
|
10
|
+
const { displayAsciiArt, clearScreen, info } = require('../utils');
|
|
11
11
|
|
|
12
12
|
async function showProgress(tsoft, theme) {
|
|
13
13
|
const themePath = path.join(process.cwd(), tsoft.site, theme);
|
|
14
14
|
const fileList = tsoft.fileManager.listFilesRecursive(themePath).filter(file => !file.includes('.env'));
|
|
15
15
|
const totalFiles = fileList.length;
|
|
16
16
|
|
|
17
|
-
// Yeni bir ilerleme çubuğu oluşturun ve shades_classic temasını kullanın
|
|
18
17
|
const progressBar = new cliProgress.SingleBar({
|
|
19
18
|
format: 'İlerleme |{bar}| {percentage}% || {value}/{total} Dosya Yüklendi',
|
|
20
19
|
barCompleteChar: '\u2588',
|
|
@@ -43,16 +42,28 @@ async function showProgress(tsoft, theme) {
|
|
|
43
42
|
return 'Tüm dosyalar ilerleme ile başarıyla yüklendi';
|
|
44
43
|
}
|
|
45
44
|
|
|
46
|
-
async function
|
|
47
|
-
await
|
|
48
|
-
console.log('Geliştirme ortamı aşağıdaki ayrıntılarla başlatılıyor:');
|
|
49
|
-
console.log(`Site Adı: ${siteName}`);
|
|
50
|
-
console.log(`Tema Adı: ${themeName}`);
|
|
45
|
+
async function initializeAndAuthorize(tsoft, themeName) {
|
|
46
|
+
await tsoft.initialize(themeName);
|
|
51
47
|
|
|
52
|
-
const
|
|
53
|
-
|
|
48
|
+
const approvalPrompt = new Input({
|
|
49
|
+
name: 'approval',
|
|
50
|
+
message: 'Lütfen onay kodunu sağlayın:'
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const approval = await approvalPrompt.run();
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
if (approval) {
|
|
56
|
+
await constants.APPROVAL.handler(tsoft.clientCredentials.setClientSecret(approval));
|
|
57
|
+
tsoft.buildEnvironment();
|
|
58
|
+
console.info('Hazırsınız');
|
|
59
|
+
return true;
|
|
60
|
+
} else {
|
|
61
|
+
console.error('Onay kodu gerekli.');
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async function handleExistingEnvironment(tsoft, themeName, themeEnvPath) {
|
|
56
67
|
let envData = {};
|
|
57
68
|
if (fs.existsSync(themeEnvPath)) {
|
|
58
69
|
try {
|
|
@@ -68,45 +79,17 @@ async function start(siteName, themeName) {
|
|
|
68
79
|
|
|
69
80
|
if (bearerTokenValid) {
|
|
70
81
|
console.info('Geçerli bir taşıyıcı jetonuna sahip mevcut ortam dosyası bulundu. Mevcut yapılandırma ile devam ediliyor...');
|
|
71
|
-
|
|
72
|
-
await startWatching(siteName, themeName, tsoft);
|
|
73
|
-
return;
|
|
82
|
+
return true;
|
|
74
83
|
} else {
|
|
75
84
|
console.warn('Mevcut taşıyıcı jetonu geçersiz. Yeniden yetkilendirmeniz gerekecek.');
|
|
76
85
|
fs.unlinkSync(themeEnvPath);
|
|
77
86
|
}
|
|
78
87
|
}
|
|
79
88
|
}
|
|
80
|
-
|
|
81
|
-
await tsoft.initialize(themeName);
|
|
82
|
-
|
|
83
|
-
const approvalPrompt = new Input({
|
|
84
|
-
name: 'approval',
|
|
85
|
-
message: 'Lütfen onay kodunu sağlayın:'
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
const approval = await approvalPrompt.run();
|
|
89
|
-
|
|
90
|
-
if (approval) {
|
|
91
|
-
await constants.APPROVAL.handler(tsoft.clientCredentials.setClientSecret(approval));
|
|
92
|
-
tsoft.buildEnvironment();
|
|
93
|
-
console.info('Hazırsınız');
|
|
94
|
-
// Dosya değişikliklerini izlemeye başlayın
|
|
95
|
-
await startWatching(siteName, themeName, tsoft);
|
|
96
|
-
} else {
|
|
97
|
-
console.error('Onay kodu gerekli.');
|
|
98
|
-
}
|
|
89
|
+
return false;
|
|
99
90
|
}
|
|
100
91
|
|
|
101
|
-
async function startWatching(
|
|
102
|
-
const themePath = path.join(process.cwd(), site, theme);
|
|
103
|
-
const envPath = path.join(themePath, `${theme}.env`);
|
|
104
|
-
|
|
105
|
-
if (!fs.existsSync(envPath)) {
|
|
106
|
-
console.error('Ortam dosyası bulunamadı. Lütfen temayı önce başlatın.');
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
|
|
92
|
+
async function startWatching(themePath, tsoft, theme) {
|
|
110
93
|
const watcher = chokidar.watch(themePath, {
|
|
111
94
|
ignored: /(^|[\/\\])(\.theme|(.*?)\.env)$/, // .theme ve .env dosyaları yoksayılır
|
|
112
95
|
persistent: true
|
|
@@ -114,41 +97,13 @@ async function startWatching(site, theme, tsoft) {
|
|
|
114
97
|
|
|
115
98
|
watcher.on('change', async (filePath) => {
|
|
116
99
|
console.log(`Dosya değiştirildi ${filePath}`);
|
|
117
|
-
|
|
118
|
-
const env = JSON.parse(fs.readFileSync(envPath, 'utf-8'));
|
|
119
|
-
const fileName = filePath.replace(`${themePath}/`, '');
|
|
120
|
-
const content = fs.readFileSync(filePath).toString();
|
|
121
|
-
|
|
122
|
-
try {
|
|
123
|
-
await tsoft.saveFile(theme, fileName, content, env.bearer);
|
|
124
|
-
console.log(`Dosya başarıyla yüklendi ${fileName}`);
|
|
125
|
-
} catch (error) {
|
|
126
|
-
console.error(`Dosya yükleme hatası ${fileName}:`, error);
|
|
127
|
-
}
|
|
100
|
+
await handleFileChange(filePath, tsoft, theme);
|
|
128
101
|
}).on('unlink', async (filePath) => {
|
|
129
102
|
console.log(`Dosya silindi ${filePath}`);
|
|
130
|
-
|
|
131
|
-
const env = JSON.parse(fs.readFileSync(envPath, 'utf-8'));
|
|
132
|
-
const fileName = filePath.replace(`${themePath}/`, '');
|
|
133
|
-
|
|
134
|
-
try {
|
|
135
|
-
await tsoft.deleteFile(theme, fileName, env.bearer);
|
|
136
|
-
console.log(`Dosya başarıyla silindi ${fileName}`);
|
|
137
|
-
} catch (error) {
|
|
138
|
-
console.error(`Dosya silme hatası ${fileName}:`, error);
|
|
139
|
-
}
|
|
103
|
+
await handleFileDeletion(filePath, tsoft, theme);
|
|
140
104
|
}).on('unlinkDir', async (dirPath) => {
|
|
141
105
|
console.log(`Dizin silindi ${dirPath}`);
|
|
142
|
-
|
|
143
|
-
const env = JSON.parse(fs.readFileSync(envPath, 'utf-8'));
|
|
144
|
-
const dirName = dirPath.replace(`${themePath}/`, '');
|
|
145
|
-
|
|
146
|
-
try {
|
|
147
|
-
await tsoft.deleteDirectory(theme, dirName, env.bearer);
|
|
148
|
-
console.log(`Dizin başarıyla silindi ${dirName}`);
|
|
149
|
-
} catch (error) {
|
|
150
|
-
console.error(`Dizin silme hatası ${dirName}:`, error);
|
|
151
|
-
}
|
|
106
|
+
await handleDirectoryDeletion(dirPath, tsoft, theme);
|
|
152
107
|
});
|
|
153
108
|
|
|
154
109
|
console.log(`${themePath} dizinindeki dosya değişiklikleri izleniyor`);
|
|
@@ -161,12 +116,56 @@ async function startWatching(site, theme, tsoft) {
|
|
|
161
116
|
info();
|
|
162
117
|
|
|
163
118
|
rl.on('line', async (input) => {
|
|
164
|
-
|
|
119
|
+
await handleUserInput(input, tsoft, theme, watcher, rl);
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
async function handleFileChange(filePath, tsoft, theme) {
|
|
124
|
+
const env = JSON.parse(fs.readFileSync(path.join(process.cwd(), tsoft.site, theme, `${theme}.env`), 'utf-8'));
|
|
125
|
+
const fileName = filePath.replace(`${path.join(process.cwd(), tsoft.site, theme)}/`, '');
|
|
126
|
+
const content = fs.readFileSync(filePath).toString();
|
|
127
|
+
|
|
128
|
+
try {
|
|
129
|
+
await tsoft.saveFile(theme, fileName, content, env.bearer);
|
|
130
|
+
console.log(`Dosya başarıyla yüklendi ${fileName}`);
|
|
131
|
+
} catch (error) {
|
|
132
|
+
console.error(`Dosya yükleme hatası ${fileName}:`, error);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
async function handleFileDeletion(filePath, tsoft, theme) {
|
|
137
|
+
const env = JSON.parse(fs.readFileSync(path.join(process.cwd(), tsoft.site, theme, `${theme}.env`), 'utf-8'));
|
|
138
|
+
const fileName = filePath.replace(`${path.join(process.cwd(), tsoft.site, theme)}/`, '');
|
|
139
|
+
|
|
140
|
+
try {
|
|
141
|
+
await tsoft.deleteFile(theme, fileName, env.bearer);
|
|
142
|
+
console.log(`Dosya başarıyla silindi ${fileName}`);
|
|
143
|
+
} catch (error) {
|
|
144
|
+
console.error(`Dosya silme hatası ${fileName}:`, error);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
async function handleDirectoryDeletion(dirPath, tsoft, theme) {
|
|
149
|
+
const env = JSON.parse(fs.readFileSync(path.join(process.cwd(), tsoft.site, theme, `${theme}.env`), 'utf-8'));
|
|
150
|
+
const dirName = dirPath.replace(`${path.join(process.cwd(), tsoft.site, theme)}/`, '');
|
|
151
|
+
|
|
152
|
+
try {
|
|
153
|
+
await tsoft.deleteDirectory(theme, dirName, env.bearer);
|
|
154
|
+
console.log(`Dizin başarıyla silindi ${dirName}`);
|
|
155
|
+
} catch (error) {
|
|
156
|
+
console.error(`Dizin silme hatası ${dirName}:`, error);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
async function handleUserInput(input, tsoft, theme, watcher, rl) {
|
|
161
|
+
switch (input.trim()) {
|
|
162
|
+
case 'q':
|
|
165
163
|
console.log('Dosya izleme işlemi sonlandırılıyor...');
|
|
166
164
|
watcher.close();
|
|
167
165
|
rl.close();
|
|
168
166
|
process.exit(0);
|
|
169
|
-
|
|
167
|
+
break;
|
|
168
|
+
case 'u':
|
|
170
169
|
console.log('Tema güncelleniyor...');
|
|
171
170
|
try {
|
|
172
171
|
const result = await updateTheme(tsoft, theme);
|
|
@@ -175,7 +174,8 @@ async function startWatching(site, theme, tsoft) {
|
|
|
175
174
|
} catch (error) {
|
|
176
175
|
console.error(`Tema güncelleme hatası:`, error);
|
|
177
176
|
}
|
|
178
|
-
|
|
177
|
+
break;
|
|
178
|
+
case 's':
|
|
179
179
|
clearScreen();
|
|
180
180
|
console.log('Tüm dosyalar ilerleme ile yüklenmeye başlanıyor...');
|
|
181
181
|
try {
|
|
@@ -185,25 +185,79 @@ async function startWatching(site, theme, tsoft) {
|
|
|
185
185
|
} catch (error) {
|
|
186
186
|
console.error(`İlerleme gösterim hatası:`, error);
|
|
187
187
|
}
|
|
188
|
-
|
|
188
|
+
break;
|
|
189
|
+
case 'e':
|
|
189
190
|
console.log('.theme dosyası düzenleniyor...');
|
|
190
191
|
try {
|
|
191
192
|
await editThemeFile(tsoft.themeManager, theme);
|
|
192
193
|
} catch (error) {
|
|
193
194
|
console.error(`.theme dosyası düzenleme hatası:`, error);
|
|
194
195
|
}
|
|
195
|
-
|
|
196
|
+
break;
|
|
197
|
+
case 'o':
|
|
196
198
|
console.log('Tema dizini açılıyor...');
|
|
197
199
|
const openCommand = process.platform === 'win32' ? 'start' :
|
|
198
200
|
process.platform === 'darwin' ? 'open' :
|
|
199
201
|
'xdg-open';
|
|
200
|
-
exec(`${openCommand} ${
|
|
202
|
+
exec(`${openCommand} ${path.join(process.cwd(), tsoft.site, theme)}`, (err) => {
|
|
201
203
|
if (err) {
|
|
202
204
|
console.error('Tema dizini açılamadı:', err);
|
|
203
205
|
} else {
|
|
204
206
|
console.log('Tema dizini başarıyla açıldı.');
|
|
205
207
|
}
|
|
206
208
|
});
|
|
209
|
+
break;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
async function start(siteName, themeName) {
|
|
214
|
+
await displayAsciiArt();
|
|
215
|
+
console.log('Geliştirme ortamı aşağıdaki ayrıntılarla başlatılıyor:');
|
|
216
|
+
console.log(`Site Adı: ${siteName}`);
|
|
217
|
+
console.log(`Tema Adı: ${themeName}`);
|
|
218
|
+
|
|
219
|
+
const tsoft = new Tsoft(siteName);
|
|
220
|
+
const themeEnvPath = path.join(process.cwd(), siteName, themeName, `${themeName}.env`);
|
|
221
|
+
|
|
222
|
+
const existingEnvValid = await handleExistingEnvironment(tsoft, themeName, themeEnvPath);
|
|
223
|
+
if (existingEnvValid) {
|
|
224
|
+
await startWatching(path.join(process.cwd(), siteName, themeName), tsoft, themeName);
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const initializedAndAuthorized = await initializeAndAuthorize(tsoft, themeName);
|
|
229
|
+
if (initializedAndAuthorized) {
|
|
230
|
+
await startWatching(path.join(process.cwd(), siteName, themeName), tsoft, themeName);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
async function updateTheme(tsoft, theme) {
|
|
235
|
+
const directoryName = path.basename(path.join(process.cwd(), tsoft.site, theme));
|
|
236
|
+
const response = await tsoft.updateTheme(directoryName);
|
|
237
|
+
if (response.status === true) {
|
|
238
|
+
return 'Successfully updated';
|
|
239
|
+
} else {
|
|
240
|
+
throw new Error('Update failed');
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
async function editThemeFile(themeManager, directoryName) {
|
|
244
|
+
const themePath = path.join(process.cwd(), themeManager.site, directoryName, '.theme');
|
|
245
|
+
|
|
246
|
+
if (!fs.existsSync(themePath)) {
|
|
247
|
+
console.error('.theme file not found.');
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
console.log(`Opening .theme file: ${themePath}`);
|
|
252
|
+
const openCommand = process.platform === 'win32' ? 'start' :
|
|
253
|
+
process.platform === 'darwin' ? 'open' :
|
|
254
|
+
'xdg-open';
|
|
255
|
+
|
|
256
|
+
exec(`${openCommand} ${themePath}`, (err) => {
|
|
257
|
+
if (err) {
|
|
258
|
+
console.error('Failed to open .theme file:', err);
|
|
259
|
+
} else {
|
|
260
|
+
console.log('.theme file opened successfully.');
|
|
207
261
|
}
|
|
208
262
|
});
|
|
209
263
|
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const {Input} = require('enquirer');
|
|
4
|
+
const {clearScreen} = require('../utils');
|
|
5
|
+
const {selectSite, createThemeDirectory} = require('./create');
|
|
6
|
+
const Tsoft = require("../tsoft");
|
|
7
|
+
const {slugify} = require('../utils');
|
|
8
|
+
const unzipper = require('unzipper');
|
|
9
|
+
|
|
10
|
+
function unzipFile(zipFilePath, extractToDir) {
|
|
11
|
+
return new Promise((resolve, reject) => {
|
|
12
|
+
fs.createReadStream(zipFilePath)
|
|
13
|
+
.pipe(unzipper.Extract({path: extractToDir}))
|
|
14
|
+
.on('close', resolve)
|
|
15
|
+
.on('error', reject);
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async function syncTheme() {
|
|
20
|
+
const cwd = process.cwd();
|
|
21
|
+
const sites = fs.readdirSync(cwd).filter(file => {
|
|
22
|
+
return file.charAt(0) !== '.' && !['node_modules', 'build', 'dist'].includes(file);
|
|
23
|
+
}).filter(file => fs.statSync(path.join(cwd, file)).isDirectory());
|
|
24
|
+
|
|
25
|
+
const selectedSite = await selectSite(sites);
|
|
26
|
+
|
|
27
|
+
const tsoft = new Tsoft(selectedSite);
|
|
28
|
+
|
|
29
|
+
const codePrompt = new Input({
|
|
30
|
+
name: 'code',
|
|
31
|
+
message: 'Lütfen kurtarma anahtarını girin:'
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const recoveryCode = await codePrompt.run();
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
const {secret, public_key} = await tsoft.startRecovery(recoveryCode);
|
|
38
|
+
|
|
39
|
+
tsoft.clientCredentials.setClientSecret(secret).setClientId(public_key)
|
|
40
|
+
const authorizeResponse = await tsoft.clientCredentials.authorize(true)
|
|
41
|
+
const themeInformation = authorizeResponse.data.tokenable;
|
|
42
|
+
|
|
43
|
+
const themeName = themeInformation.name;
|
|
44
|
+
const themeNameSlug = slugify(themeName);
|
|
45
|
+
const themePath = await createThemeDirectory(selectedSite, themeNameSlug);
|
|
46
|
+
|
|
47
|
+
const themeData = {
|
|
48
|
+
site: selectedSite,
|
|
49
|
+
name: themeName,
|
|
50
|
+
author: themeInformation.author,
|
|
51
|
+
version: themeInformation.version
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
fs.writeFileSync(path.join(themePath, '.theme'), JSON.stringify(themeData, null, 2));
|
|
55
|
+
tsoft.themeManager.setTheme(themeNameSlug)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
if (!fs.existsSync(themePath)) {
|
|
59
|
+
fs.mkdirSync(themePath, {recursive: true});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
clearScreen();
|
|
63
|
+
|
|
64
|
+
const zipFilePath = path.join(themePath, 'theme.zip');
|
|
65
|
+
|
|
66
|
+
console.log('Zip dosyası indiriliyor...');
|
|
67
|
+
await tsoft.fileManager.downloadAndSaveZip(themePath, zipFilePath, tsoft.clientCredentials.bearer);
|
|
68
|
+
console.log('İndirme tamamlandı.');
|
|
69
|
+
|
|
70
|
+
console.log('Dosyalar çıkarılıyor...');
|
|
71
|
+
await unzipFile(zipFilePath, themePath);
|
|
72
|
+
console.log('Çıkarma işlemi tamamlandı.');
|
|
73
|
+
fs.unlinkSync(zipFilePath);
|
|
74
|
+
|
|
75
|
+
tsoft.buildEnvironment();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
module.exports = {
|
|
79
|
+
syncTheme
|
|
80
|
+
};
|
package/src/file-manager.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const utils = require('./utils');
|
|
4
|
+
const { exec } = require('child_process');
|
|
5
|
+
const {buildDownloadZipRequest} = require('./request');
|
|
4
6
|
|
|
5
7
|
class FileManager {
|
|
6
8
|
constructor(site) {
|
|
@@ -34,6 +36,35 @@ class FileManager {
|
|
|
34
36
|
const ext = path.extname(file).substring(1);
|
|
35
37
|
return utils.allowedExtensions.includes(ext);
|
|
36
38
|
}
|
|
39
|
+
|
|
40
|
+
async downloadAndSaveZip(saveToDir, zipFilePath, bearerToken) {
|
|
41
|
+
// Fetch the zip file and save it
|
|
42
|
+
const response = await buildDownloadZipRequest(this.site, `api/v3/admin/online-store-2/theme/download-theme`, {
|
|
43
|
+
headers: {
|
|
44
|
+
'Content-Type': 'application/zip',
|
|
45
|
+
'Accept': 'application/zip',
|
|
46
|
+
'Authorization': `Bearer ${bearerToken}`
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
fs.writeFileSync(zipFilePath, Buffer.from(response));
|
|
52
|
+
|
|
53
|
+
console.log(`Zip dosyası ${zipFilePath} konumuna kaydedildi.`);
|
|
54
|
+
|
|
55
|
+
// Open the directory in file explorer
|
|
56
|
+
const openCommand = process.platform === 'win32' ? 'start' :
|
|
57
|
+
process.platform === 'darwin' ? 'open' :
|
|
58
|
+
'xdg-open';
|
|
59
|
+
exec(`${openCommand} ${saveToDir}`, (err) => {
|
|
60
|
+
if (err) {
|
|
61
|
+
console.error('Dizin açılamadı:', err);
|
|
62
|
+
} else {
|
|
63
|
+
console.log(`Dizin açıldı: ${saveToDir}`);
|
|
64
|
+
console.log('Lütfen zip dosyasını bu dizine çıkartın.');
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
37
68
|
}
|
|
38
69
|
|
|
39
70
|
module.exports = FileManager;
|
package/src/request.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
buildPostRequest = (site, uri, options = {}) => {
|
|
2
2
|
return fetch("https://" + site + '/' + uri, {
|
|
3
3
|
method: 'POST',
|
|
4
4
|
headers: {
|
|
@@ -14,3 +14,24 @@ module.exports = (site, uri, options = {}) => {
|
|
|
14
14
|
})
|
|
15
15
|
.catch((error) => console.error(error));
|
|
16
16
|
}
|
|
17
|
+
buildDownloadZipRequest = (site, uri, options = {}) => {
|
|
18
|
+
return fetch("https://" + site + '/' + uri, {
|
|
19
|
+
method: 'POST',
|
|
20
|
+
headers: {
|
|
21
|
+
'Content-Type': 'application/zip',
|
|
22
|
+
'Accept': 'application/zip',
|
|
23
|
+
...options.headers ?? {}
|
|
24
|
+
},
|
|
25
|
+
body: options.body
|
|
26
|
+
})
|
|
27
|
+
.then((response) => response.arrayBuffer())
|
|
28
|
+
.then((result) => {
|
|
29
|
+
return result
|
|
30
|
+
})
|
|
31
|
+
.catch((error) => console.error(error));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
module.exports = {
|
|
35
|
+
buildPostRequest,
|
|
36
|
+
buildDownloadZipRequest
|
|
37
|
+
}
|
package/src/theme-manager.js
CHANGED
package/src/tsoft.js
CHANGED
|
@@ -3,7 +3,7 @@ const constants = require('./constants');
|
|
|
3
3
|
const FileManager = require('./file-manager');
|
|
4
4
|
const ThemeManager = require('./theme-manager');
|
|
5
5
|
const path = require("path");
|
|
6
|
-
const buildPostRequest = require('./request');
|
|
6
|
+
const {buildPostRequest} = require('./request');
|
|
7
7
|
|
|
8
8
|
class Tsoft {
|
|
9
9
|
static TSOFT_CLI_UUID = '7583a318-8542-4ec8-980c-48ea67031be3';
|
|
@@ -49,7 +49,7 @@ class Tsoft {
|
|
|
49
49
|
const fileName = this.fileManager.getRelativePath(theme, file);
|
|
50
50
|
const content = this.fileManager.readFile(file);
|
|
51
51
|
const env = this.themeManager.getEnvironment(theme);
|
|
52
|
-
|
|
52
|
+
await buildPostRequest(this.site, Tsoft.ONLINESTORE_SAVE_URI, {
|
|
53
53
|
headers: {
|
|
54
54
|
Authorization: `Bearer ${env.bearer}`
|
|
55
55
|
},
|
|
@@ -133,6 +133,10 @@ class Tsoft {
|
|
|
133
133
|
});
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
+
async startRecovery(token) {
|
|
137
|
+
return await this.clientCredentials.recovery(token);
|
|
138
|
+
}
|
|
139
|
+
|
|
136
140
|
}
|
|
137
141
|
|
|
138
142
|
module.exports = Tsoft;
|