tsoft-cli 2.0.0 → 2.0.5

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.
Files changed (60) hide show
  1. package/README.md +29 -94
  2. package/{packages/theme/bin → bin}/run.js +2 -0
  3. package/package.json +45 -6
  4. package/.editorconfig +0 -11
  5. package/.github/workflows/node.js.yml +0 -25
  6. package/.nvmrc +0 -1
  7. package/.prettierrc.json +0 -8
  8. package/.vscode/extensions.json +0 -3
  9. package/.vscode/settings.json +0 -4
  10. package/CHANGELOG.md +0 -113
  11. package/packages/cli/README.md +0 -53
  12. package/packages/cli/bin/dev.js +0 -5
  13. package/packages/cli/bin/run.cmd +0 -3
  14. package/packages/cli/bin/run.js +0 -5
  15. package/packages/cli/enums.ts +0 -4
  16. package/packages/cli/index.ts +0 -11
  17. package/packages/cli/package.json +0 -59
  18. package/packages/cli/tsconfig.json +0 -9
  19. package/packages/shared/index.ts +0 -6
  20. package/packages/shared/package.json +0 -45
  21. package/packages/shared/src/cli-progress.ts +0 -3
  22. package/packages/shared/src/commands/cli-all-commands.ts +0 -6
  23. package/packages/shared/src/commands/version-command.ts +0 -12
  24. package/packages/shared/src/consola.ts +0 -1
  25. package/packages/shared/src/open.ts +0 -3
  26. package/packages/shared/src/unzip.ts +0 -15
  27. package/packages/shared/tsconfig.json +0 -9
  28. package/packages/theme/bin/dev.js +0 -5
  29. package/packages/theme/bin/run.cmd +0 -3
  30. package/packages/theme/index.ts +0 -21
  31. package/packages/theme/jest.config.ts +0 -3
  32. package/packages/theme/package.json +0 -66
  33. package/packages/theme/src/commands/theme/create.ts +0 -51
  34. package/packages/theme/src/commands/theme/delete-site.ts +0 -30
  35. package/packages/theme/src/commands/theme/delete-theme.ts +0 -39
  36. package/packages/theme/src/commands/theme/dev.ts +0 -47
  37. package/packages/theme/src/commands/theme/pull.ts +0 -26
  38. package/packages/theme/src/enums.ts +0 -55
  39. package/packages/theme/src/services/ClientCredentials.ts +0 -127
  40. package/packages/theme/src/services/Constants.ts +0 -19
  41. package/packages/theme/src/services/CreateTheme.ts +0 -88
  42. package/packages/theme/src/services/DeleteSite.ts +0 -30
  43. package/packages/theme/src/services/DeleteTheme.ts +0 -46
  44. package/packages/theme/src/services/FileManager.ts +0 -62
  45. package/packages/theme/src/services/Request.ts +0 -18
  46. package/packages/theme/src/services/StartTheme.ts +0 -363
  47. package/packages/theme/src/services/SyncTheme.ts +0 -108
  48. package/packages/theme/src/services/ThemeManager.ts +0 -118
  49. package/packages/theme/src/services/Tsoft.ts +0 -151
  50. package/packages/theme/src/services/types.ts +0 -90
  51. package/packages/theme/src/types.ts +0 -20
  52. package/packages/theme/src/utils/screen.ts +0 -28
  53. package/packages/theme/src/utils/utils.ts +0 -83
  54. package/packages/theme/tests/FileManager.test.js +0 -90
  55. package/packages/theme/tsconfig.json +0 -9
  56. package/pnpm-workspace.yaml +0 -2
  57. package/pull_request_template.md +0 -5
  58. package/scripts/prebuild.js +0 -45
  59. package/scripts/versions.js +0 -70
  60. package/tsconfig.build.json +0 -21
@@ -1,62 +0,0 @@
1
- import fs from 'node:fs'
2
- import path from 'node:path'
3
- import { consola } from '@tsoft-cli/shared'
4
- import { Request } from './Request.js'
5
- import { allowedExtensions, themeTypes } from '../enums.js'
6
- import type { TAllowedExtensions, TThemeTypes } from '../types.js'
7
- import { getFolderFromCWD, setPathForWebhookOperations } from '../utils/utils.js'
8
-
9
- export class FileManager {
10
- private site: string
11
-
12
- constructor(site: string) {
13
- this.site = site
14
- }
15
-
16
- listFilesRecursive(directory: string, fileList: string[] = []): string[] {
17
- const files = fs.readdirSync(directory)
18
-
19
- files.forEach((file) => {
20
- const fullPath = path.join(directory, file)
21
- if (fs.statSync(fullPath).isDirectory()) {
22
- this.listFilesRecursive(fullPath, fileList)
23
- } else {
24
- this.isAllowedExtension(fullPath) && fileList.push(fullPath)
25
- }
26
- })
27
-
28
- return fileList
29
- }
30
-
31
- getRelativePath(theme: string, file: string): string {
32
- return setPathForWebhookOperations(file.replace(getFolderFromCWD(this.site, theme), ''))
33
- }
34
-
35
- readFile(file: string): string {
36
- return fs.readFileSync(file).toString()
37
- }
38
-
39
- isAllowedExtension(file: string): boolean {
40
- const ext = path.extname(file).substring(1) as TAllowedExtensions
41
- return allowedExtensions.includes(ext)
42
- }
43
-
44
- async downloadThemeZip(zipFilePath: string, bearerToken: string, type: TThemeTypes = themeTypes.none): Promise<void> {
45
- const response = await Request.request<Buffer>(
46
- this.site,
47
- `api/v3/admin/online-store-2/theme/download-theme?type=${type}`,
48
- {
49
- method: 'POST',
50
- responseType: 'arraybuffer',
51
- headers: {
52
- 'Content-Type': 'application/zip',
53
- Accept: 'application/zip',
54
- Authorization: `Bearer ${bearerToken}`,
55
- },
56
- },
57
- )
58
-
59
- fs.writeFileSync(zipFilePath, response)
60
- consola.success(`Zip dosyası ${zipFilePath} konumuna kaydedildi.`)
61
- }
62
- }
@@ -1,18 +0,0 @@
1
- import axios from 'axios'
2
- import type { AxiosRequestConfig } from 'axios'
3
- import { consola } from '@tsoft-cli/shared'
4
-
5
- export class Request {
6
- public static async request<T>(site: string, path: string, options: AxiosRequestConfig = {}): Promise<T> {
7
- return axios
8
- .request({
9
- url: `https://${site}/${path}`,
10
- ...options,
11
- })
12
- .then((response) => response.data)
13
- .catch((error) => {
14
- consola.error(error)
15
- throw new Error('Request failed')
16
- })
17
- }
18
- }
@@ -1,363 +0,0 @@
1
- import fs from 'node:fs'
2
- import path from 'node:path'
3
- import { exec } from 'node:child_process'
4
- import { openBrowser, unZIP, cliProgress, consola } from '@tsoft-cli/shared'
5
- import chokidar from 'chokidar'
6
- import type { FSWatcher } from 'chokidar'
7
- import { input } from '@inquirer/prompts'
8
- import type { Tsoft } from './Tsoft.js'
9
- import { Constants } from './Constants.js'
10
- import type { TThemeEnviroments } from '../types.js'
11
- import { themeFileNames, themeTypes } from '../enums.js'
12
- import { getFolderFromCWD, getOpenFilePlatformCode, saveThemeData, setPathForWebhookOperations } from '../utils/utils.js'
13
- import { clearScreen, displayAsciiArt } from '../utils/screen.js'
14
-
15
- export class StartTheme {
16
- private tsoft: Tsoft
17
- private themeName: string
18
- private watcher: FSWatcher
19
-
20
- constructor(TS: Tsoft) {
21
- this.tsoft = TS
22
- }
23
-
24
- private async showProgress(): Promise<string> {
25
- const themePath = getFolderFromCWD(this.tsoft.site, this.themeName)
26
- const fileList = this.tsoft.fileManager
27
- .listFilesRecursive(themePath)
28
- .filter((file: string) => !file.includes(themeFileNames.env) && !file.includes(themeFileNames.themeTxt))
29
- fileList.push(path.join(themePath, themeFileNames.theme))
30
- const totalFiles = fileList.length
31
-
32
- const progressBar = new cliProgress.SingleBar({
33
- format: 'İlerleme |{bar}| {percentage}% || {value}/{total} Dosya Yüklendi',
34
- barCompleteChar: '\u2588',
35
- barIncompleteChar: '\u2591',
36
- hideCursor: true,
37
- clearOnComplete: true,
38
- })
39
- progressBar.start(totalFiles, 0)
40
-
41
- for (let i = 0; i < totalFiles; i++) {
42
- const file = fileList[i]
43
- const fileName = this.tsoft.fileManager.getRelativePath(this.themeName, file)
44
- const content = this.tsoft.fileManager.readFile(file)
45
- const env = this.tsoft.themeManager.getEnvironment(this.themeName)
46
-
47
- try {
48
- await this.tsoft.saveFile(this.themeName, fileName, content, env.bearer)
49
- } catch (error) {
50
- consola.error(`Dosya yükleme hatası ${fileName}:`, error)
51
- }
52
- progressBar.update(i + 1)
53
- }
54
-
55
- progressBar.stop()
56
-
57
- return 'Tüm dosyalar başarıyla yüklendi'
58
- }
59
-
60
- private async initializeAndAuthorize(): Promise<boolean> {
61
- await this.tsoft.initialize(this.themeName)
62
-
63
- const approval = await input({
64
- message: 'Lütfen onay kodunu sağlayın:',
65
- required: true,
66
- })
67
-
68
- if (approval) {
69
- await Constants.APPROVAL.handler(this.tsoft.clientCredentials.setClientSecret(approval))
70
- this.tsoft.buildEnvironment()
71
- consola.success('Ortam dosyası başarıyla oluşturuldu.')
72
- return true
73
- } else {
74
- consola.error('Onay kodu gerekli.')
75
- return false
76
- }
77
- }
78
-
79
- private async handleExistingEnvironment(themeEnvPath: string): Promise<boolean> {
80
- let envData: TThemeEnviroments = {} as any
81
-
82
- if (fs.existsSync(themeEnvPath)) {
83
- try {
84
- envData = JSON.parse(fs.readFileSync(themeEnvPath, 'utf-8'))
85
- } catch (error) {
86
- consola.warn(
87
- `${themeEnvPath} dosyasında geçersiz JSON formatı. Bu dosya silinecek ve yeniden yetkilendirmeniz gerekecek.`,
88
- )
89
- fs.unlinkSync(themeEnvPath)
90
- consola.info('Geçersiz ortam dosyası silindi. Başlatma işlemine devam ediliyor...')
91
- }
92
-
93
- if (envData.bearer) {
94
- const bearerTokenValid = await this.tsoft.isTokenValid(this.themeName)
95
-
96
- if (bearerTokenValid) {
97
- consola.info(
98
- 'Geçerli bir taşıyıcı jetonuna sahip mevcut ortam dosyası bulundu. Mevcut yapılandırma ile devam ediliyor...',
99
- )
100
- return true
101
- } else {
102
- consola.warn('Mevcut taşıyıcı jetonu geçersiz. Yeniden yetkilendirmeniz gerekecek.')
103
- fs.unlinkSync(themeEnvPath)
104
- }
105
- }
106
- }
107
-
108
- return false
109
- }
110
-
111
- private async changedThemeTxt() {
112
- const themeTXT = getFolderFromCWD(this.tsoft.site, this.themeName, themeFileNames.themeTxt)
113
- const themeFile = getFolderFromCWD(this.tsoft.site, this.themeName)
114
- const result = fs.readFileSync(themeTXT).toString()
115
- saveThemeData(themeFile, JSON.parse(result))
116
- }
117
-
118
- private async startWatching(themePath: string): Promise<void> {
119
- this.watcher = chokidar.watch(themePath, {
120
- ignored: /(^|[\/\\])(\.theme|(.*?)\.env)$/, // ignore .theme ve .env files
121
- persistent: true,
122
- })
123
-
124
- this.watcher
125
- .on('change', async (filePath: string) => {
126
- if (filePath.includes(themeFileNames.themeTxt)) {
127
- await this.changedThemeTxt()
128
- return
129
- }
130
-
131
- consola.info(`Dosya değiştirildi ${filePath}`)
132
- await this.handleFileChange(filePath)
133
- })
134
- .on('unlink', async (filePath: string) => {
135
- consola.success(`Dosya silindi ${filePath}`)
136
- await this.handleFileDeletion(filePath)
137
- })
138
- .on('unlinkDir', async (dirPath: string) => {
139
- consola.success(`Dizin silindi ${dirPath}`)
140
- await this.handleDirectoryDeletion(dirPath)
141
- })
142
-
143
- consola.start(`${themePath} dizinindeki dosya değişiklikleri izleniyor`)
144
-
145
- const developmentURL = this.usageScreen()
146
-
147
- process.stdin.setRawMode(true)
148
- process.stdin.resume()
149
- process.stdin.on('data', async (key) => {
150
- await this.handleUserInput(key, developmentURL)
151
- })
152
- }
153
-
154
- private usageScreen(): string {
155
- clearScreen()
156
-
157
- consola.log(
158
- '\n' +
159
- '********************************************************\n' +
160
- '* *\n' +
161
- '* Dosya izlemeyi sonlandırmak için "q" tuşuna basın, *\n' +
162
- '* Temayı güncellemek için "u" tuşuna basın, *\n' +
163
- '* Temayı kaydetmek için "s" tuşuna basın, *\n' +
164
- '* .theme dosyasını düzenlemek için "e" tuşuna basın, *\n' +
165
- '* Tema dizinini açmak için "o" tuşuna basın. *\n' +
166
- '* URL\'yi tarayıcıda açmak için "p" tuşuna basın. *\n' +
167
- '* *\n' +
168
- '********************************************************\n',
169
- )
170
-
171
- const { clientId, clientSecret } = this.tsoft.themeManager.getEnvironment(this.themeName)
172
- const url = 'https://' + this.tsoft.site + '?tsoft-cli=' + clientId + '&tsoft-cli-secret=' + clientSecret
173
- consola.info('İzlenen tema: ' + this.themeName)
174
- consola.info('Önizleme: \n')
175
- consola.info(url + '\n')
176
-
177
- return url
178
- }
179
-
180
- private async closeProcess(): Promise<void> {
181
- consola.log('\n')
182
- consola.info('Programdan çıkılıyor. Hoşça kalın!')
183
- await this.watcher.close()
184
- process.exit(0)
185
- }
186
-
187
- private async handleUserInput(input: Buffer, url: string): Promise<void> {
188
- //CTRL+C
189
- if (input[0] == 3) {
190
- await this.closeProcess()
191
- }
192
-
193
- switch (input.toString().trim()) {
194
- case 'p':
195
- consola.start('URL tarayıcıda açılıyor...')
196
- await openBrowser(url)
197
- break
198
-
199
- case 'u':
200
- consola.start('Tema güncelleniyor...')
201
- try {
202
- const result = await this.updateTheme()
203
- consola.success(result)
204
- } catch (error) {
205
- consola.error(`Tema güncelleme hatası:`, error)
206
- }
207
- break
208
-
209
- case 's':
210
- consola.start('Tüm dosyalar ilerleme ile yüklenmeye başlanıyor...')
211
- try {
212
- const result = await this.showProgress()
213
- consola.success(result)
214
- } catch (error) {
215
- consola.error(`İlerleme gösterim hatası:`, error)
216
- }
217
- break
218
-
219
- case 'e':
220
- consola.start(`${themeFileNames.theme} dosyası düzenleniyor...`)
221
- try {
222
- await this.editThemeFile()
223
- } catch (error) {
224
- consola.error(`${themeFileNames.theme} dosyası düzenleme hatası:`, error)
225
- }
226
- break
227
-
228
- case 'o':
229
- consola.start('Tema dizini açılıyor...')
230
- exec(`${getOpenFilePlatformCode()} ${getFolderFromCWD(this.tsoft.site, this.themeName)}`, (err) => {
231
- if (err) {
232
- consola.error('Tema dizini açılamadı:', err)
233
- } else {
234
- consola.success('Tema dizini başarıyla açıldı.')
235
- }
236
- })
237
- break
238
-
239
- case 'q':
240
- await this.closeProcess()
241
- }
242
- }
243
-
244
- private async handleFileChange(filePath: string): Promise<void> {
245
- const { dirname, env } = this.setFileDirectoryOptions(filePath)
246
- const content = fs.readFileSync(filePath).toString()
247
-
248
- try {
249
- await this.tsoft.saveFile(this.themeName, dirname, content, env.bearer)
250
- consola.success(`Dosya başarıyla yüklendi ${dirname}`)
251
- } catch (error) {
252
- consola.error(`Dosya yükleme hatası ${dirname}:`, error)
253
- }
254
- }
255
-
256
- private async handleFileDeletion(filePath: string): Promise<void> {
257
- const { dirname, env } = this.setFileDirectoryOptions(filePath)
258
-
259
- try {
260
- await this.tsoft.deleteFile(this.themeName, dirname, env.bearer)
261
- consola.success(`Dosya başarıyla silindi ${dirname}`)
262
- } catch (error) {
263
- consola.error(`Dosya silme hatası ${dirname}:`, error)
264
- }
265
- }
266
-
267
- private async handleDirectoryDeletion(dirPath: string): Promise<void> {
268
- const { dirname, env } = this.setFileDirectoryOptions(dirPath)
269
-
270
- try {
271
- await this.tsoft.deleteDirectory(this.themeName, dirname, env.bearer)
272
- consola.success(`Dizin başarıyla silindi ${dirname}`)
273
- } catch (error) {
274
- consola.error(`Dizin silme hatası ${dirname}:`, error)
275
- }
276
- }
277
-
278
- private setFileDirectoryOptions(dir: string): { dirname: string; env: TThemeEnviroments } {
279
- return {
280
- dirname: setPathForWebhookOperations(dir.replace(`${getFolderFromCWD(this.tsoft.site, this.themeName)}`, '')),
281
- env: JSON.parse(
282
- fs.readFileSync(
283
- getFolderFromCWD(this.tsoft.site, this.themeName, `${this.themeName}${themeFileNames.env}`),
284
- 'utf-8',
285
- ),
286
- ) as TThemeEnviroments,
287
- }
288
- }
289
-
290
- private async updateTheme(): Promise<string> {
291
- const directoryName = path.basename(getFolderFromCWD(this.tsoft.site, this.themeName))
292
- const response = await this.tsoft.updateTheme(directoryName)
293
-
294
- if (response.status == true) {
295
- return 'Successfully updated'
296
- }
297
-
298
- throw new Error('Update failed')
299
- }
300
-
301
- private async editThemeFile(): Promise<void> {
302
- const themePath = getFolderFromCWD(this.tsoft.themeManager.site, this.themeName, themeFileNames.themeTxt)
303
- if (!fs.existsSync(themePath)) {
304
- consola.error(`${themeFileNames.themeTxt} file not found.`)
305
- return
306
- }
307
-
308
- consola.start(`Opening ${themeFileNames.themeTxt} file: ${themePath}`)
309
-
310
- exec(`${getOpenFilePlatformCode()} ${themePath}`, (err) => {
311
- if (err) {
312
- consola.error(`Failed to open ${themeFileNames.themeTxt} file:`, err)
313
- } else {
314
- consola.success(`${themeFileNames.themeTxt} file opened successfully.`)
315
- }
316
- })
317
- }
318
-
319
- public async start(themeName: string, recentlyCreated: boolean = false): Promise<void> {
320
- this.themeName = themeName
321
- await displayAsciiArt()
322
- consola.start('Geliştirme ortamı aşağıdaki ayrıntılarla başlatılıyor:')
323
- consola.info(`Site Adı: ${this.tsoft.site}`)
324
- consola.info(`Tema Adı: ${this.themeName}`)
325
- const themePath = getFolderFromCWD(this.tsoft.site, this.themeName)
326
- const themeEnvPath = getFolderFromCWD(this.tsoft.site, this.themeName, `${this.themeName}${themeFileNames.env}`)
327
-
328
- const existingEnvValid = await this.handleExistingEnvironment(themeEnvPath)
329
- if (existingEnvValid) {
330
- await this.startWatching(themePath)
331
- return
332
- }
333
-
334
- const initializedAndAuthorized = await this.initializeAndAuthorize()
335
- if (initializedAndAuthorized) {
336
- if (recentlyCreated) {
337
- const defaultZipFile = getFolderFromCWD(this.tsoft.site, this.themeName, themeFileNames.themeZip)
338
-
339
- consola.start('Default tema dosyaları indirme işlemi başlatılıyor, lütfen bekleyin')
340
- await this.tsoft.fileManager.downloadThemeZip(
341
- defaultZipFile,
342
- this.tsoft.clientCredentials.bearer,
343
- themeTypes.default,
344
- )
345
- consola.success('Default tema dosyaları indirildi.')
346
-
347
- consola.start('Zip dosyası çıkarma işlemi başlatılıyor.')
348
- const unzipResult = await unZIP(defaultZipFile, themePath)
349
- if (!unzipResult) {
350
- consola.error('Zip dosyası çıkarılamadı')
351
- throw new Error()
352
- }
353
-
354
- consola.success('Zip dosyası çıkarma işlemi tamamlandı.')
355
-
356
- //delete zip
357
- fs.unlinkSync(defaultZipFile)
358
- }
359
-
360
- await this.startWatching(themePath)
361
- }
362
- }
363
- }
@@ -1,108 +0,0 @@
1
- import fs from 'node:fs'
2
- import path from 'node:path'
3
- import { unZIP, consola } from '@tsoft-cli/shared'
4
- import { input } from '@inquirer/prompts'
5
- import { CreateTheme } from './CreateTheme.js'
6
- import { StartTheme } from './StartTheme.js'
7
- import { Tsoft } from './Tsoft.js'
8
- import { clearScreen } from '../utils/screen.js'
9
- import { themeFileNames } from '../enums.js'
10
- import { saveThemeTxt, slugify } from '../utils/utils.js'
11
- import type { TClientCredentialsRecoveryData, TThemeFile } from './types.js'
12
-
13
- export class SyncTheme {
14
- private tsoft: Tsoft
15
- private createTheme: CreateTheme
16
-
17
- constructor(TS: Tsoft, CT: CreateTheme) {
18
- this.tsoft = TS
19
- this.createTheme = CT
20
- }
21
-
22
- public async start() {
23
- let recoveryCode: string
24
- let recoveryData: TClientCredentialsRecoveryData
25
- while (!recoveryData) {
26
- recoveryCode = await input({
27
- message: 'Lütfen kurtarma anahtarını girin:',
28
- required: true,
29
- })
30
-
31
- if (!recoveryData) {
32
- continue
33
- }
34
-
35
- try {
36
- recoveryData = await this.tsoft.startRecovery(recoveryCode)
37
- } catch (error) {
38
- consola.error(`Hata: ${error.message}`)
39
- if (error.message.includes('Çok fazla deneme yapıldı')) {
40
- return
41
- }
42
-
43
- continue
44
- }
45
-
46
- if (!recoveryData) {
47
- consola.error('Kurtarma işlemi başarısız oldu. Lütfen geçerli bir kurtarma anahtarı girin.')
48
- }
49
- }
50
-
51
- const { secret, public_key } = recoveryData
52
-
53
- this.tsoft.clientCredentials.setClientSecret(secret).setClientId(public_key)
54
- const authorizeResponse = await this.tsoft.clientCredentials.authorize()
55
- if (!authorizeResponse) {
56
- consola.error('Authorize işlemi başarısız oldu.')
57
- throw new Error('Authorize işlemi başarısız oldu.')
58
- }
59
-
60
- const themeInformation = authorizeResponse.data.tokenable
61
-
62
- if (!themeInformation) {
63
- consola.error('Tokenable bilgisi alınamadı.')
64
- throw new Error('Tokenable bilgisi alınamadı.')
65
- }
66
-
67
- const themeName = themeInformation.name
68
- const themeNameSlug = slugify(themeName)
69
- const themePath = await this.createTheme.createThemeDirectory(this.tsoft.site, themeNameSlug)
70
-
71
- const themeData: TThemeFile = {
72
- site: this.tsoft.site,
73
- name: themeName,
74
- author: themeInformation.author,
75
- version: themeInformation.version,
76
- }
77
-
78
- saveThemeTxt(themePath, themeData)
79
- this.tsoft.themeManager.setTheme(themeNameSlug)
80
- clearScreen()
81
-
82
- const zipFilePath = path.join(themePath, themeFileNames.themeZip)
83
-
84
- try {
85
- consola.start('Zip dosyası indiriliyor...')
86
- await this.tsoft.fileManager.downloadThemeZip(zipFilePath, this.tsoft.clientCredentials.bearer)
87
- consola.success('İndirme tamamlandı.')
88
-
89
- consola.start('Dosyalar çıkarılıyor...')
90
- const unzipResult = await unZIP(zipFilePath, themePath)
91
- if (!unzipResult) {
92
- throw 'Zip dosyası çıkarılamadı'
93
- }
94
-
95
- consola.success('Çıkarma işlemi tamamlandı.')
96
- fs.unlinkSync(zipFilePath)
97
- } catch (error) {
98
- consola.error(`Zip dosyası ile ilgili bir hata oluştu: ${error.message}`)
99
- return
100
- }
101
-
102
- this.tsoft.buildEnvironment()
103
-
104
- const startTheme = new StartTheme(this.tsoft)
105
- // Geliştirme ortamını başlat
106
- await startTheme.start(themeNameSlug)
107
- }
108
- }
@@ -1,118 +0,0 @@
1
- import fs from 'node:fs'
2
- import http from 'node:http'
3
- import https from 'node:https'
4
- import { consola } from '@tsoft-cli/shared'
5
- import { getFolderFromCWD, slugify } from '../utils/utils.js'
6
- import type { TClientCredentialsGetEnvironment, TThemeFile } from './types.js'
7
- import type { TThemeEnviroments } from '../types.js'
8
- import { themeFileNames } from '../enums.js'
9
-
10
- export class ThemeManager {
11
- public site: string
12
- public theme: string
13
- public registered: boolean
14
-
15
- constructor(site: string) {
16
- this.site = site
17
- this.theme = null
18
- this.registered = false
19
- }
20
-
21
- public async initializeTheme(theme: string, reInit = false) {
22
- this.theme = theme
23
- const themePath = getFolderFromCWD(this.site, theme)
24
- const themeEnvPath = getFolderFromCWD(this.site, theme, `${theme}${themeFileNames.env}`)
25
-
26
- if (reInit) {
27
- // await fs.rm(themePath, {recursive: true, force: true}, (err, file) => {});
28
- }
29
-
30
- if (!fs.existsSync(getFolderFromCWD(this.site))) {
31
- fs.mkdirSync(getFolderFromCWD(this.site))
32
- }
33
- if (!fs.existsSync(themePath)) {
34
- fs.mkdirSync(themePath)
35
- }
36
- if (reInit || !fs.existsSync(themeEnvPath)) {
37
- fs.writeFileSync(themeEnvPath, '')
38
- this.registered = false
39
- } else {
40
- const data = fs.readFileSync(themeEnvPath)
41
- try {
42
- const environment = JSON.parse(data.toString()) as TThemeEnviroments
43
- this.registered = Boolean(environment.bearer)
44
- } catch (e) {
45
- this.registered = false
46
- }
47
- }
48
-
49
- try {
50
- const isValid = await this.checkSiteValidity()
51
- if (!isValid) {
52
- consola.error('Geçersiz site: Siteye ulaşılamıyor.')
53
- return false
54
- }
55
- } catch (error) {
56
- consola.error('Geçersiz site: Siteye ulaşılamıyor.', error.message)
57
- return false
58
- }
59
-
60
- return true
61
- }
62
-
63
- public setTheme(theme: string) {
64
- this.theme = slugify(theme)
65
- }
66
-
67
- public isRegistered() {
68
- return this.registered
69
- }
70
-
71
- public buildEnvironment(environment: TClientCredentialsGetEnvironment) {
72
- const envPath = getFolderFromCWD(this.site, this.theme, `${this.theme}${themeFileNames.env}`)
73
- fs.writeFileSync(envPath, JSON.stringify(environment))
74
- }
75
-
76
- public getEnvironment(theme: string): TThemeEnviroments {
77
- const themeEnvPath = getFolderFromCWD(this.site, slugify(theme), `${slugify(theme)}${themeFileNames.env}`)
78
- return JSON.parse(fs.readFileSync(themeEnvPath).toString())
79
- }
80
-
81
- public getThemeInfo(directoryName: string): TThemeFile {
82
- const themePath = getFolderFromCWD(this.site, slugify(directoryName), themeFileNames.themeTxt)
83
-
84
- if (fs.existsSync(themePath)) {
85
- const themeInfo = fs.readFileSync(themePath, 'utf-8')
86
- try {
87
- return JSON.parse(themeInfo)
88
- } catch (error) {
89
- consola.error(`${themeFileNames.themeTxt} dosyasını ayrıştırma hatası:`, error)
90
- return null
91
- }
92
- } else {
93
- consola.error(`${themeFileNames.themeTxt} dosyası bulunamadı:`, themePath)
94
- return null
95
- }
96
- }
97
-
98
- public checkSiteValidity(): Promise<boolean> {
99
- return new Promise((resolve, reject) => {
100
- const url = new URL(`https://${this.site}/Y/R`)
101
- const request = url.protocol == 'https:' ? https : http
102
-
103
- const req = request.get(url, (res) => {
104
- if (res.statusCode === 200) {
105
- return resolve(true)
106
- }
107
-
108
- return resolve(false)
109
- })
110
-
111
- req.on('error', (err) => {
112
- return reject(err)
113
- })
114
-
115
- req.end()
116
- })
117
- }
118
- }