tsoft-cli 1.4.3 → 2.0.0

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 (72) hide show
  1. package/.editorconfig +11 -0
  2. package/.github/workflows/node.js.yml +25 -0
  3. package/.nvmrc +1 -0
  4. package/.prettierrc.json +8 -0
  5. package/.vscode/extensions.json +3 -0
  6. package/.vscode/settings.json +4 -0
  7. package/CHANGELOG.md +29 -4
  8. package/package.json +14 -25
  9. package/packages/cli/README.md +53 -0
  10. package/packages/cli/bin/dev.js +5 -0
  11. package/packages/cli/bin/run.cmd +3 -0
  12. package/packages/cli/bin/run.js +5 -0
  13. package/packages/cli/enums.ts +4 -0
  14. package/packages/cli/index.ts +11 -0
  15. package/packages/cli/package.json +59 -0
  16. package/packages/cli/tsconfig.json +9 -0
  17. package/packages/shared/index.ts +6 -0
  18. package/packages/shared/package.json +45 -0
  19. package/packages/shared/src/cli-progress.ts +3 -0
  20. package/packages/shared/src/commands/cli-all-commands.ts +6 -0
  21. package/packages/shared/src/commands/version-command.ts +12 -0
  22. package/packages/shared/src/consola.ts +1 -0
  23. package/packages/shared/src/open.ts +3 -0
  24. package/packages/shared/src/unzip.ts +15 -0
  25. package/packages/shared/tsconfig.json +9 -0
  26. package/packages/theme/bin/dev.js +5 -0
  27. package/packages/theme/bin/run.cmd +3 -0
  28. package/packages/theme/bin/run.js +5 -0
  29. package/packages/theme/index.ts +21 -0
  30. package/packages/theme/jest.config.ts +3 -0
  31. package/packages/theme/package.json +66 -0
  32. package/packages/theme/src/commands/theme/create.ts +51 -0
  33. package/packages/theme/src/commands/theme/delete-site.ts +30 -0
  34. package/packages/theme/src/commands/theme/delete-theme.ts +39 -0
  35. package/packages/theme/src/commands/theme/dev.ts +47 -0
  36. package/packages/theme/src/commands/theme/pull.ts +26 -0
  37. package/packages/theme/src/enums.ts +55 -0
  38. package/packages/theme/src/services/ClientCredentials.ts +127 -0
  39. package/packages/theme/src/services/Constants.ts +19 -0
  40. package/packages/theme/src/services/CreateTheme.ts +88 -0
  41. package/packages/theme/src/services/DeleteSite.ts +30 -0
  42. package/packages/theme/src/services/DeleteTheme.ts +46 -0
  43. package/packages/theme/src/services/FileManager.ts +62 -0
  44. package/packages/theme/src/services/Request.ts +18 -0
  45. package/packages/theme/src/services/StartTheme.ts +363 -0
  46. package/packages/theme/src/services/SyncTheme.ts +108 -0
  47. package/packages/theme/src/services/ThemeManager.ts +118 -0
  48. package/packages/theme/src/services/Tsoft.ts +151 -0
  49. package/packages/theme/src/services/types.ts +90 -0
  50. package/packages/theme/src/types.ts +20 -0
  51. package/packages/theme/src/utils/screen.ts +28 -0
  52. package/packages/theme/src/utils/utils.ts +83 -0
  53. package/packages/theme/tests/FileManager.test.js +90 -0
  54. package/packages/theme/tsconfig.json +9 -0
  55. package/pnpm-workspace.yaml +2 -0
  56. package/pull_request_template.md +5 -0
  57. package/scripts/prebuild.js +45 -0
  58. package/scripts/versions.js +70 -0
  59. package/tsconfig.build.json +21 -0
  60. package/bin/index.js +0 -77
  61. package/jest.config.js +0 -3
  62. package/src/Tsoft.js +0 -137
  63. package/src/commands/CreateCommand.js +0 -102
  64. package/src/commands/StartCommand.js +0 -281
  65. package/src/commands/SyncCommand.js +0 -97
  66. package/src/core/ClientCredentials.js +0 -107
  67. package/src/core/Constants.js +0 -19
  68. package/src/core/FileManager.js +0 -53
  69. package/src/core/Request.js +0 -41
  70. package/src/core/ThemeManager.js +0 -113
  71. package/src/core/Utils.js +0 -104
  72. package/tests/FileManager.test.js +0 -90
@@ -0,0 +1,151 @@
1
+ import path from 'node:path'
2
+ import { consola } from '@tsoft-cli/shared'
3
+ import { ClientCredentials } from './ClientCredentials.js'
4
+ import { Constants } from './Constants.js'
5
+ import { FileManager } from './FileManager.js'
6
+ import { ThemeManager } from './ThemeManager.js'
7
+ import { Request } from './Request.js'
8
+ import type { TUpdateThemeResponse } from '../types.js'
9
+ import type { TClientCredentialsRecoveryData } from './types.js'
10
+ import { themeFileNames } from '../enums.js'
11
+
12
+ export class Tsoft {
13
+ public site: string
14
+ public themeManager: ThemeManager
15
+ public fileManager: FileManager
16
+ public clientCredentials: ClientCredentials
17
+ private TSOFT_CLI_UUID = '7583a318-8542-4ec8-980c-48ea67031be3'
18
+ private ONLINESTORE_SAVE_URI = 'api/v3/admin/online-store-2/theme/file-manager?q=save'
19
+ private ONLINESTORE_DELETE_URI = 'api/v3/admin/online-store-2/theme/file-manager?q=delete'
20
+ private UPDATE_THEME_URI = 'api/v3/admin/online-store-2/theme/update-theme'
21
+
22
+ constructor(site: string) {
23
+ this.site = site
24
+ this.themeManager = new ThemeManager(site)
25
+ this.fileManager = new FileManager(site)
26
+ this.clientCredentials = new ClientCredentials(site)
27
+ }
28
+
29
+ async initialize(theme: string, reInit: boolean = false) {
30
+ await this.themeManager.initializeTheme(theme, reInit)
31
+ if (!this.themeManager.isRegistered()) {
32
+ return this.register(this.TSOFT_CLI_UUID, this.themeManager.getThemeInfo(theme))
33
+ } else {
34
+ consola.warn('You are already registered')
35
+ }
36
+ }
37
+
38
+ buildEnvironment() {
39
+ this.themeManager.buildEnvironment(this.clientCredentials.getEnvironment())
40
+ }
41
+
42
+ async authorize() {
43
+ await this.clientCredentials.authorize()
44
+ }
45
+
46
+ async register(CLIENT_UUID: string, clientConfiguration = {}) {
47
+ const response = await this.clientCredentials.register(CLIENT_UUID, clientConfiguration)
48
+ return response === true ? Constants.APPROVAL : null
49
+ }
50
+
51
+ async saveOnlineStore(theme: string) {
52
+ const fileList = this.fileManager.listFilesRecursive(path.join(process.cwd(), this.site, theme))
53
+
54
+ await Promise.all(
55
+ fileList
56
+ .filter((file) => !file.includes(themeFileNames.env))
57
+ .map(async (file) => {
58
+ const fileName = this.fileManager.getRelativePath(theme, file)
59
+ const content = this.fileManager.readFile(file)
60
+ const env = this.themeManager.getEnvironment(theme)
61
+
62
+ await Request.request(this.site, this.ONLINESTORE_SAVE_URI, {
63
+ method: 'POST',
64
+ headers: {
65
+ Authorization: `Bearer ${env.bearer}`,
66
+ Accept: 'application/json',
67
+ 'Content-Type': 'application/json',
68
+ },
69
+ data: {
70
+ theme: theme,
71
+ path: fileName,
72
+ content: content,
73
+ },
74
+ })
75
+ }),
76
+ )
77
+ }
78
+
79
+ async saveFile(theme: string, fileName: string, content: string, bearerToken: string) {
80
+ return Request.request(this.site, this.ONLINESTORE_SAVE_URI, {
81
+ method: 'POST',
82
+ headers: {
83
+ Authorization: `Bearer ${bearerToken}`,
84
+ Accept: 'application/json',
85
+ 'Content-Type': 'application/json',
86
+ },
87
+ data: {
88
+ theme: theme,
89
+ path: fileName,
90
+ content: content,
91
+ },
92
+ })
93
+ }
94
+
95
+ async deleteFile(theme: string, fileName: string, bearerToken: string) {
96
+ return Request.request(this.site, this.ONLINESTORE_DELETE_URI, {
97
+ method: 'POST',
98
+ headers: {
99
+ Authorization: `Bearer ${bearerToken}`,
100
+ Accept: 'application/json',
101
+ 'Content-Type': 'application/json',
102
+ },
103
+ data: {
104
+ theme: theme,
105
+ items: [{ type: 'file', path: fileName }],
106
+ },
107
+ })
108
+ }
109
+
110
+ async deleteDirectory(theme: string, folderName: string, bearerToken: string) {
111
+ return Request.request(this.site, this.ONLINESTORE_DELETE_URI, {
112
+ method: 'POST',
113
+ headers: {
114
+ Authorization: `Bearer ${bearerToken}`,
115
+ Accept: 'application/json',
116
+ 'Content-Type': 'application/json',
117
+ },
118
+ data: {
119
+ theme: theme,
120
+ items: [{ type: 'dir', path: folderName }],
121
+ },
122
+ })
123
+ }
124
+
125
+ async isTokenValid(theme: string) {
126
+ const env = this.themeManager.getEnvironment(theme)
127
+ return this.clientCredentials.validateToken(env.bearer)
128
+ }
129
+
130
+ async updateTheme(directoryName: string) {
131
+ const env = this.themeManager.getEnvironment(directoryName)
132
+ const themeInfo = this.themeManager.getThemeInfo(directoryName) // .theme bilgisi alınıyor
133
+
134
+ return Request.request<TUpdateThemeResponse>(this.site, this.UPDATE_THEME_URI, {
135
+ method: 'POST',
136
+ headers: {
137
+ Authorization: `Bearer ${env.bearer}`,
138
+ Accept: 'application/json',
139
+ 'Content-Type': 'application/json',
140
+ },
141
+ data: {
142
+ theme: directoryName,
143
+ themeInfo: themeInfo,
144
+ },
145
+ })
146
+ }
147
+
148
+ async startRecovery(token: string): Promise<TClientCredentialsRecoveryData> {
149
+ return this.clientCredentials.recovery(token)
150
+ }
151
+ }
@@ -0,0 +1,90 @@
1
+ export type TClientCredentialsGetEnvironment = {
2
+ site: string
3
+ clientId: string
4
+ clientSecret: string
5
+ bearer: string
6
+ }
7
+
8
+ export type TThemeFile = {
9
+ site: string
10
+ name: string
11
+ author: string
12
+ version: string
13
+ }
14
+
15
+ export type TAuthorizeResponse = {
16
+ status: boolean
17
+ message: string
18
+ data: {
19
+ token: {
20
+ accessToken: {
21
+ name: string
22
+ abilities: string[]
23
+ expires_at: null
24
+ tokenable_id: number
25
+ tokenable_type: string
26
+ ip_address: string
27
+ updated_at: string
28
+ created_at: string
29
+ id: number
30
+ }
31
+ plainTextToken: string
32
+ }
33
+ tokenable?: {
34
+ name: string
35
+ author: string
36
+ version: string
37
+ }
38
+ }
39
+ attributes: {
40
+ 'system.status': {
41
+ event: string
42
+ message: string
43
+ }
44
+ }
45
+ }
46
+
47
+ export type TAuthMeResponse = {
48
+ status: boolean
49
+ message: string
50
+ data: {
51
+ id: number
52
+ name: string
53
+ is_active: number
54
+ }
55
+ attributes: {
56
+ 'system.status': {
57
+ event: string
58
+ message: string
59
+ }
60
+ }
61
+ }
62
+
63
+ export type TAuthApplication = {
64
+ status: boolean
65
+ message: string
66
+ data: {
67
+ public_key: string
68
+ }
69
+ attributes: {
70
+ 'system.status': {
71
+ event: string
72
+ message: string
73
+ }
74
+ }
75
+ }
76
+
77
+ export type TClientCredentialsRecoveryResponse = {
78
+ status: boolean
79
+ data: {
80
+ secret: string
81
+ public_key: string
82
+ }
83
+ throttle?: {
84
+ limit: string
85
+ retryAfter: string
86
+ resetDate: string
87
+ }
88
+ }
89
+
90
+ export type TClientCredentialsRecoveryData = Pick<TClientCredentialsRecoveryResponse['data'], 'public_key' | 'secret'>
@@ -0,0 +1,20 @@
1
+ import { allowedExtensions, menuSelections, themeTypes } from './enums.js'
2
+
3
+ export type ValueOf<T> = T[keyof T]
4
+
5
+ export type TMainMenuSelections = ValueOf<typeof menuSelections>
6
+
7
+ export type TUpdateThemeResponse = {
8
+ status: boolean
9
+ }
10
+
11
+ export type TThemeEnviroments = {
12
+ site: string
13
+ clientId: string
14
+ clientSecret: string
15
+ bearer: string
16
+ }
17
+
18
+ export type TThemeTypes = ValueOf<typeof themeTypes>
19
+
20
+ export type TAllowedExtensions = (typeof allowedExtensions)[number]
@@ -0,0 +1,28 @@
1
+ import figlet from 'figlet'
2
+ import { consola } from '@tsoft-cli/shared'
3
+ import { packageJson } from '../enums.js'
4
+
5
+ export async function displayAsciiArt(): Promise<void> {
6
+ return new Promise<void>((resolve, reject) => {
7
+ figlet(
8
+ 'T-SOFT CLI',
9
+ {
10
+ font: 'Standard',
11
+ },
12
+ (err, data) => {
13
+ if (err) {
14
+ consola.error(err)
15
+ return reject(err)
16
+ }
17
+ consola.log(data)
18
+ return resolve()
19
+ },
20
+ )
21
+ }).then(() => {
22
+ consola.info('Versiyon: ' + packageJson.version)
23
+ })
24
+ }
25
+
26
+ export function clearScreen(): void {
27
+ process.stdout.write('\x1B[2J\x1B[0f')
28
+ }
@@ -0,0 +1,83 @@
1
+ import fs from 'node:fs'
2
+ import path from 'node:path'
3
+ import { themeFileNames } from '../enums.js'
4
+ import type { TThemeFile } from '../services/types.js'
5
+
6
+ export function getNonThemeFolders(): string[] {
7
+ return ['node_modules', 'build', 'dist']
8
+ }
9
+
10
+ export function checkThemeSiteFolder(value: string): boolean {
11
+ return new RegExp(/\b\w+\.com(\.tr)?\b/g).test(value)
12
+ }
13
+
14
+ export function getLocalSites(opt: { cwd?: string } = {}): string[] {
15
+ const cwd = opt.cwd ?? process.cwd()
16
+
17
+ return fs
18
+ .readdirSync(cwd)
19
+ .filter((file) => {
20
+ const filePath = path.join(cwd, file)
21
+
22
+ return (
23
+ checkThemeSiteFolder(file) &&
24
+ fs.statSync(filePath).isDirectory() &&
25
+ fs.existsSync(path.join(filePath, themeFileNames.tsoft))
26
+ )
27
+ })
28
+ .filter((file) => fs.statSync(path.join(cwd, file)).isDirectory())
29
+ }
30
+
31
+ export function slugify(text: string): string {
32
+ return text
33
+ .toString()
34
+ .toLowerCase()
35
+ .replace(/\s+/g, '-')
36
+ .replace(/[^\w\-]+/g, '')
37
+ .replace(/\-\-+/g, '-')
38
+ .replace(/^-+/, '')
39
+ .replace(/-+$/, '')
40
+ }
41
+
42
+ export function getPlatform(): NodeJS.Platform {
43
+ return process.platform
44
+ }
45
+
46
+ export function getFolderFromCWD(...paths: string[]): string {
47
+ return path.join(process.cwd(), ...paths)
48
+ }
49
+
50
+ export function getDirectories(source: string): string[] {
51
+ return fs
52
+ .readdirSync(source)
53
+ .filter((file) => checkThemeSiteFolder(file))
54
+ .filter((file) => fs.statSync(path.join(source, file)).isDirectory())
55
+ }
56
+
57
+ export function getThemesFromFolder(source: string): string[] {
58
+ return fs
59
+ .readdirSync(source)
60
+ .filter((file) => file.charAt(0) !== '.' && !getNonThemeFolders().includes(file))
61
+ .filter((file) => fs.statSync(path.join(source, file)).isDirectory())
62
+ }
63
+
64
+ export function getOpenFilePlatformCode() {
65
+ return getPlatform() == 'win32' ? 'start' : getPlatform() == 'darwin' ? 'open' : 'xdg-open'
66
+ }
67
+
68
+ /**
69
+ * İşlemlerin düzgün çalışması için ters slash(\) yerine düz slash yapmamız lazım gerekiyor.
70
+ * @param {string} path
71
+ * @returns {string}
72
+ */
73
+ export function setPathForWebhookOperations(path: string): string {
74
+ return path.replace(/\\/g, '/')
75
+ }
76
+
77
+ export function saveThemeData(themePath: string, themeData: TThemeFile): void {
78
+ fs.writeFileSync(path.join(themePath, themeFileNames.theme), JSON.stringify(themeData, null, 2))
79
+ }
80
+
81
+ export function saveThemeTxt(themePath: string, themeData: TThemeFile): void {
82
+ fs.writeFileSync(path.join(themePath, themeFileNames.themeTxt), JSON.stringify(themeData, null, 2))
83
+ }
@@ -0,0 +1,90 @@
1
+ const path = require('node:path')
2
+ const mockFs = require('mock-fs')
3
+ const FileManager = require('../src/file-manager')
4
+
5
+ describe('FileManager', () => {
6
+ const site = 'testSite'
7
+ const fileManager = new FileManager(site)
8
+
9
+ beforeEach(() => {
10
+ mockFs({
11
+ '/testDir': {
12
+ 'file1.js': 'console.log("file1");',
13
+ 'file2.css': 'body { margin: 0; }',
14
+ subdir: {
15
+ 'file3.jpg': '',
16
+ 'file4.png': '',
17
+ },
18
+ },
19
+ [`${process.cwd()}/${site}`]: {
20
+ myTheme: {
21
+ 'file.js': 'console.log("test");',
22
+ },
23
+ },
24
+ })
25
+ })
26
+
27
+ afterEach(() => {
28
+ mockFs.restore()
29
+ })
30
+
31
+ describe('listFilesRecursive', () => {
32
+ it('should list all files recursively', () => {
33
+ // Act
34
+ const result = fileManager.listFilesRecursive('/testDir')
35
+
36
+ // Assert
37
+ expect(result).toEqual([
38
+ '/testDir/file1.js',
39
+ '/testDir/file2.css',
40
+ '/testDir/subdir/file3.jpg',
41
+ '/testDir/subdir/file4.png',
42
+ ])
43
+ })
44
+ })
45
+
46
+ describe('getRelativePath', () => {
47
+ it('should get the relative path of a file', () => {
48
+ // Arrange
49
+ const theme = 'myTheme'
50
+ const file = path.join(process.cwd(), site, theme, 'file.js')
51
+ const expectedRelativePath = 'file.js'
52
+
53
+ // Act
54
+ const result = fileManager.getRelativePath(theme, file)
55
+
56
+ // Assert
57
+ expect(result).toBe(expectedRelativePath)
58
+ })
59
+ })
60
+
61
+ describe('readFile', () => {
62
+ it('should read the contents of a file', () => {
63
+ // Arrange
64
+ const file = '/testDir/file1.js'
65
+ const fileContents = 'console.log("file1");'
66
+
67
+ // Act
68
+ const result = fileManager.readFile(file)
69
+
70
+ // Assert
71
+ expect(result).toBe(fileContents)
72
+ })
73
+ })
74
+
75
+ describe('isAllowedExtension', () => {
76
+ it('should return true for allowed extensions', () => {
77
+ // Arrange
78
+ const allowedFile = 'file.js'
79
+ const notAllowedFile = 'file.exe'
80
+
81
+ // Act
82
+ const isAllowedFileResult = fileManager.isAllowedExtension(allowedFile)
83
+ const isNotAllowedFileResult = fileManager.isAllowedExtension(notAllowedFile)
84
+
85
+ // Assert
86
+ expect(isAllowedFileResult).toBe(true)
87
+ expect(isNotAllowedFileResult).toBe(false)
88
+ })
89
+ })
90
+ })
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "../../tsconfig.build.json",
3
+ "compilerOptions": {
4
+ "outDir": "build"
5
+ },
6
+ "include": [
7
+ "**/*"
8
+ ]
9
+ }
@@ -0,0 +1,2 @@
1
+ packages:
2
+ - packages/*
@@ -0,0 +1,5 @@
1
+ # Pull Request Check List
2
+
3
+ - [ ] Check all options by manuel test.
4
+
5
+ Thanks For Your Contribution 🥳
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Her build alma işleminden önce paketlerin içindeki build klasörlerini siler.
3
+ */
4
+
5
+ import fs from 'node:fs'
6
+ import path from 'node:path'
7
+
8
+ const cwd = process.cwd()
9
+ const packages = 'packages'
10
+ const build = 'build'
11
+
12
+ /**
13
+ * Packages içindeki klasör isimlerini alır.
14
+ * @param {string} source
15
+ * @returns {string[]} cli, shared, ...
16
+ */
17
+ function getPackagesFolder(source) {
18
+ return fs.readdirSync(source).filter((file) => fs.statSync(path.join(source, file)).isDirectory())
19
+ }
20
+
21
+ /**
22
+ * Packages klasörü içindeki paketlerin build dosyalarını siler.
23
+ * @param {string} pkgName
24
+ */
25
+ function removeBuildFiles(pkgName) {
26
+ return new Promise((resolve, reject) => {
27
+ fs.rm(path.join(cwd, packages, pkgName, build), { recursive: true, force: true }, (err) => {
28
+ if (err) {
29
+ return reject(err)
30
+ }
31
+
32
+ return resolve()
33
+ })
34
+ })
35
+ }
36
+
37
+ function start() {
38
+ const packagesFolderNames = getPackagesFolder(path.join(cwd, packages))
39
+
40
+ for (const pkgName of packagesFolderNames) {
41
+ removeBuildFiles(pkgName)
42
+ }
43
+ }
44
+
45
+ start()
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Her build alma işleminden sonra package.json içindeki bağımlılıklardan versiyonu workspace:* olanların gerçek versiyonlarını yerine yazar.
3
+ */
4
+
5
+ import fs from 'node:fs'
6
+ import path from 'node:path'
7
+
8
+ const cwd = process.cwd()
9
+ const packages = 'packages'
10
+ const packageJSON = 'package.json'
11
+
12
+ /**
13
+ * Packages içindeki klasör isimlerini alır.
14
+ * @param {string} source
15
+ * @returns {string[]} cli, shared, ...
16
+ */
17
+ function getPackagesFolder(source) {
18
+ return fs.readdirSync(source).filter((file) => fs.statSync(path.join(source, file)).isDirectory())
19
+ }
20
+
21
+ /**
22
+ * Packages klasörü içindeki package.json dosyalarını alır.
23
+ * @param {string} pkgName
24
+ * @returns {string}
25
+ */
26
+ function getPackagesPackageJsons(pkgName) {
27
+ return fs.readFileSync(path.join(cwd, packages, pkgName, packageJSON)).toString()
28
+ }
29
+
30
+ /**
31
+ * Packages klasörü içindeki paketlerin package.json dosyalarını değiştirir.
32
+ * @param {string} pkgName
33
+ * @param {string} data
34
+ */
35
+ function setPackagesPackageJsons(pkgName, data) {
36
+ return fs.writeFileSync(path.join(cwd, packages, pkgName, packageJSON), JSON.stringify(data, null, 2))
37
+ }
38
+
39
+ let packageStore = []
40
+
41
+ function start() {
42
+ const packagesFolderNames = getPackagesFolder(path.join(cwd, packages))
43
+
44
+ //Packages içindeki paketlerin isimlerini ve versiyonları aldık.
45
+ for (const pkgName of packagesFolderNames) {
46
+ const parsedPackageJSON = JSON.parse(getPackagesPackageJsons(pkgName))
47
+ packageStore.push({
48
+ name: parsedPackageJSON.name,
49
+ version: parsedPackageJSON.version,
50
+ })
51
+ }
52
+
53
+ //Packages içindeki paketlerin gerçek versiyonlarını bağımlılıklarda düzenledik.
54
+ for (const pkgName of packagesFolderNames) {
55
+ const parsedPackageJSON = JSON.parse(getPackagesPackageJsons(pkgName))
56
+
57
+ for (const pkg of packageStore) {
58
+ if (parsedPackageJSON.dependencies && parsedPackageJSON.dependencies[pkg.name]) {
59
+ parsedPackageJSON.dependencies[pkg.name] = pkg.version
60
+ }
61
+ if (parsedPackageJSON.devDependencies && parsedPackageJSON.devDependencies[pkg.name]) {
62
+ parsedPackageJSON.devDependencies[pkg.name] = pkg.version
63
+ }
64
+ }
65
+
66
+ setPackagesPackageJsons(pkgName, parsedPackageJSON)
67
+ }
68
+ }
69
+
70
+ start()
@@ -0,0 +1,21 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "NodeNext",
5
+ "moduleResolution": "NodeNext",
6
+ "esModuleInterop": true,
7
+ "allowSyntheticDefaultImports": true,
8
+ "sourceMap": true,
9
+ "outDir": "build",
10
+ "resolveJsonModule": true,
11
+ "declaration": true,
12
+ "noImplicitAny": true,
13
+ "strictNullChecks": false,
14
+ "skipLibCheck": true,
15
+ "forceConsistentCasingInFileNames": true,
16
+ "lib": [ "ESNext" ],
17
+ },
18
+ "ts-node": {
19
+ "esm": true
20
+ }
21
+ }
package/bin/index.js DELETED
@@ -1,77 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const { Select } = require('enquirer');
4
- const StartCommand = require('../src/commands/StartCommand');
5
- const SyncCommand = require('../src/commands/SyncCommand');
6
- const CreateCommand = require('../src/commands/CreateCommand');
7
- const { clearScreen, displayAsciiArt, getSites } = require('../src/core/Utils');
8
- const fs = require('fs');
9
- const path = require('path');
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
-
27
- async function selectSiteAndTheme() {
28
- const cwd = process.cwd();
29
- const sites = await getSites({
30
- cwd: cwd
31
- });
32
-
33
- if (sites.length === 0) {
34
- console.error('Mevcut dizinde site bulunamadı.');
35
- return null;
36
- }
37
-
38
- const selectedSite = await selectFromChoices('Bir site seçin:', sites);
39
- const themes = await getDirectories(path.join(cwd, selectedSite));
40
-
41
- if (themes.length === 0) {
42
- console.error('Seçilen site dizininde tema bulunamadı.');
43
- return null;
44
- }
45
-
46
- const selectedTheme = await selectFromChoices('Bir tema seçin:', themes);
47
-
48
- return { siteName: selectedSite, themeName: selectedTheme };
49
- }
50
-
51
- async function showMainMenu() {
52
- clearScreen();
53
- await displayAsciiArt();
54
-
55
- const commandChoices = ['Yeni bir tema oluştur', 'Geliştirme ortamını başlat', 'Uzak sunucudan dosyaları indir', 'Çıkış'];
56
- const selectedCommand = await selectFromChoices('Bir komut seçin:', commandChoices);
57
-
58
- switch (selectedCommand) {
59
- case 'Yeni bir tema oluştur':
60
- await CreateCommand.createTheme();
61
- break;
62
- case 'Geliştirme ortamını başlat':
63
- const selection = await selectSiteAndTheme();
64
- if (selection) {
65
- await StartCommand.start(selection.siteName, selection.themeName);
66
- }
67
- break;
68
- case 'Uzak sunucudan dosyaları indir':
69
- await SyncCommand.syncTheme();
70
- break;
71
- case 'Çıkış':
72
- console.log('Programdan çıkılıyor. Hoşça kalın!');
73
- process.exit(0);
74
- }
75
- }
76
-
77
- showMainMenu();