clapp-pm 1.0.18__py3-none-any.whl → 1.0.20__py3-none-any.whl

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.
@@ -0,0 +1,361 @@
1
+ # clapp Geliştirici Rehberi
2
+
3
+ Bu rehber, clapp için uygulama geliştirmek isteyen geliştiriciler için hazırlanmıştır.
4
+
5
+ ## 📋 İçindekiler
6
+
7
+ 1. [Başlangıç](#başlangıç)
8
+ 2. [Manifest Dosyası](#manifest-dosyası)
9
+ 3. [Desteklenen Diller](#desteklenen-diller)
10
+ 4. [Uygulama Yapısı](#uygulama-yapısı)
11
+ 5. [Bağımlılık Yönetimi](#bağımlılık-yönetimi)
12
+ 6. [Test ve Doğrulama](#test-ve-doğrulama)
13
+ 7. [Yayınlama](#yayınlama)
14
+ 8. [En İyi Uygulamalar](#en-iyi-uygulamalar)
15
+
16
+ ## 🚀 Başlangıç
17
+
18
+ ### Yeni Uygulama Oluşturma
19
+
20
+ Yeni bir clapp uygulaması oluşturmak için:
21
+
22
+ ```bash
23
+ # Python uygulaması oluştur
24
+ clapp new python my-app
25
+
26
+ # Lua uygulaması oluştur
27
+ clapp new lua my-lua-app
28
+
29
+ # Diğer diller için
30
+ clapp new dart my-dart-app
31
+ clapp new go my-go-app
32
+ clapp new rust my-rust-app
33
+ ```
34
+
35
+ ### Manuel Oluşturma
36
+
37
+ Eğer `clapp new` komutu henüz mevcut değilse, manuel olarak oluşturabilirsiniz:
38
+
39
+ 1. Yeni bir klasör oluşturun
40
+ 2. `manifest.json` dosyası ekleyin
41
+ 3. Giriş dosyanızı oluşturun
42
+ 4. Gerekli dosyaları ekleyin
43
+
44
+ ## 📄 Manifest Dosyası
45
+
46
+ Her clapp uygulaması bir `manifest.json` dosyasına sahip olmalıdır.
47
+
48
+ ### Zorunlu Alanlar
49
+
50
+ ```json
51
+ {
52
+ "name": "my-app",
53
+ "version": "1.0.0",
54
+ "language": "python",
55
+ "entry": "main.py"
56
+ }
57
+ ```
58
+
59
+ ### Opsiyonel Alanlar
60
+
61
+ ```json
62
+ {
63
+ "name": "my-app",
64
+ "version": "1.0.0",
65
+ "language": "python",
66
+ "entry": "main.py",
67
+ "description": "Uygulama açıklaması",
68
+ "author": "Geliştirici Adı",
69
+ "license": "MIT",
70
+ "dependencies": ["other-app"],
71
+ "tags": ["utility", "tool"],
72
+ "category": "productivity"
73
+ }
74
+ ```
75
+
76
+ ### Alan Açıklamaları
77
+
78
+ - **name**: Uygulama adı (benzersiz olmalı)
79
+ - **version**: Sürüm numarası (semantic versioning önerilir)
80
+ - **language**: Programlama dili (python, lua, dart, go, rust, vb.)
81
+ - **entry**: Giriş dosyası (uygulamanın başlangıç noktası)
82
+ - **description**: Uygulama açıklaması
83
+ - **author**: Geliştirici bilgisi
84
+ - **license**: Lisans bilgisi
85
+ - **dependencies**: Bağımlılık listesi (diğer clapp uygulamaları)
86
+ - **tags**: Etiketler (arama için)
87
+ - **category**: Kategori (store, productivity, game, vb.)
88
+
89
+ ## 🌐 Desteklenen Diller
90
+
91
+ ### Python
92
+ - **Dosya uzantısı**: `.py`
93
+ - **Giriş noktası**: `python main.py`
94
+ - **Örnek**: `main.py`
95
+
96
+ ### Lua
97
+ - **Dosya uzantısı**: `.lua`
98
+ - **Giriş noktası**: `lua main.lua`
99
+ - **Örnek**: `main.lua`
100
+
101
+ ### Dart
102
+ - **Dosya uzantısı**: `.dart`
103
+ - **Giriş noktası**: `dart main.dart`
104
+ - **Örnek**: `main.dart`
105
+
106
+ ### Go
107
+ - **Dosya uzantısı**: `.go`
108
+ - **Giriş noktası**: `go run main.go`
109
+ - **Örnek**: `main.go`
110
+
111
+ ### Rust
112
+ - **Dosya uzantısı**: `.rs`
113
+ - **Giriş noktası**: `cargo run`
114
+ - **Örnek**: `Cargo.toml` + `src/main.rs`
115
+
116
+ ### Node.js
117
+ - **Dosya uzantısı**: `.js`
118
+ - **Giriş noktası**: `node main.js`
119
+ - **Örnek**: `main.js`
120
+
121
+ ### Bash
122
+ - **Dosya uzantısı**: `.sh`
123
+ - **Giriş noktası**: `bash main.sh`
124
+ - **Örnek**: `main.sh`
125
+
126
+ ### Perl
127
+ - **Dosya uzantısı**: `.pl`
128
+ - **Giriş noktası**: `perl main.pl`
129
+ - **Örnek**: `main.pl`
130
+
131
+ ### Ruby
132
+ - **Dosya uzantısı**: `.rb`
133
+ - **Giriş noktası**: `ruby main.rb`
134
+ - **Örnek**: `main.rb`
135
+
136
+ ### PHP
137
+ - **Dosya uzantısı**: `.php`
138
+ - **Giriş noktası**: `php main.php`
139
+ - **Örnek**: `main.php`
140
+
141
+ ## 📁 Uygulama Yapısı
142
+
143
+ ### Temel Yapı
144
+
145
+ ```
146
+ my-app/
147
+ ├── manifest.json # Zorunlu
148
+ ├── main.py # Giriş dosyası (manifest'te belirtilen)
149
+ ├── README.md # Opsiyonel
150
+ ├── requirements.txt # Python bağımlılıkları (opsiyonel)
151
+ └── assets/ # Statik dosyalar (opsiyonel)
152
+ ├── images/
153
+ └── data/
154
+ ```
155
+
156
+ ### Örnek Python Uygulaması
157
+
158
+ **manifest.json:**
159
+ ```json
160
+ {
161
+ "name": "hello-world",
162
+ "version": "1.0.0",
163
+ "language": "python",
164
+ "entry": "main.py",
165
+ "description": "Basit bir Hello World uygulaması",
166
+ "author": "Geliştirici",
167
+ "tags": ["example", "hello"]
168
+ }
169
+ ```
170
+
171
+ **main.py:**
172
+ ```python
173
+ #!/usr/bin/env python3
174
+
175
+ def main():
176
+ print("Merhaba Dünya!")
177
+ print("Bu bir clapp uygulamasıdır.")
178
+
179
+ if __name__ == "__main__":
180
+ main()
181
+ ```
182
+
183
+ ### Örnek Lua Uygulaması
184
+
185
+ **manifest.json:**
186
+ ```json
187
+ {
188
+ "name": "lua-calculator",
189
+ "version": "1.0.0",
190
+ "language": "lua",
191
+ "entry": "main.lua",
192
+ "description": "Basit hesap makinesi",
193
+ "tags": ["calculator", "math"]
194
+ }
195
+ ```
196
+
197
+ **main.lua:**
198
+ ```lua
199
+ #!/usr/bin/env lua
200
+
201
+ function main()
202
+ print("Lua Hesap Makinesi")
203
+ print("2 + 2 = " .. (2 + 2))
204
+ end
205
+
206
+ main()
207
+ ```
208
+
209
+ ## 🔗 Bağımlılık Yönetimi
210
+
211
+ ### clapp Bağımlılıkları
212
+
213
+ Manifest dosyasında diğer clapp uygulamalarını bağımlılık olarak belirtebilirsiniz:
214
+
215
+ ```json
216
+ {
217
+ "name": "my-app",
218
+ "version": "1.0.0",
219
+ "language": "python",
220
+ "entry": "main.py",
221
+ "dependencies": ["database-app", "auth-app"]
222
+ }
223
+ ```
224
+
225
+ ### Sistem Bağımlılıkları
226
+
227
+ Her dil için sistem bağımlılıkları farklı şekilde yönetilir:
228
+
229
+ #### Python
230
+ - `requirements.txt` dosyası kullanın
231
+ - `pip install -r requirements.txt` otomatik çalışır
232
+
233
+ #### Node.js
234
+ - `package.json` dosyası kullanın
235
+ - `npm install` otomatik çalışır
236
+
237
+ #### Rust
238
+ - `Cargo.toml` dosyası kullanın
239
+ - `cargo build` otomatik çalışır
240
+
241
+ ### Bağımlılık Kontrolü
242
+
243
+ ```bash
244
+ # Uygulama bağımlılıklarını kontrol et
245
+ clapp dependency check my-app
246
+
247
+ # Bağımlılık ağacını göster
248
+ clapp dependency tree my-app
249
+ ```
250
+
251
+ ## 🧪 Test ve Doğrulama
252
+
253
+ ### Uygulama Doğrulama
254
+
255
+ ```bash
256
+ # Uygulama klasörünü doğrula
257
+ clapp validate ./my-app
258
+ ```
259
+
260
+ ### Test Çalıştırma
261
+
262
+ ```bash
263
+ # Uygulamayı test et
264
+ clapp run my-app
265
+ ```
266
+
267
+ ### Bağımlılık Testi
268
+
269
+ ```bash
270
+ # Bağımlılıkları test et
271
+ clapp dependency check my-app
272
+ ```
273
+
274
+ ## 📦 Yayınlama
275
+
276
+ ### Yerel Test
277
+
278
+ ```bash
279
+ # Uygulamayı yerel olarak test et
280
+ clapp install ./my-app
281
+ clapp run my-app
282
+ ```
283
+
284
+ ### Paket Oluşturma
285
+
286
+ ```bash
287
+ # Paket oluştur
288
+ clapp publish ./my-app
289
+ ```
290
+
291
+ ### GitHub'a Yükleme
292
+
293
+ ```bash
294
+ # GitHub'a otomatik yükle
295
+ clapp publish ./my-app --push
296
+ ```
297
+
298
+ ## ✅ En İyi Uygulamalar
299
+
300
+ ### 1. İsimlendirme
301
+ - Uygulama adları küçük harf ve tire kullanın: `my-app`
302
+ - Açıklayıcı isimler seçin
303
+ - Benzersiz isimler kullanın
304
+
305
+ ### 2. Sürüm Yönetimi
306
+ - Semantic versioning kullanın: `1.0.0`
307
+ - Her değişiklikte sürüm artırın
308
+ - CHANGELOG.md dosyası ekleyin
309
+
310
+ ### 3. Dokümantasyon
311
+ - README.md dosyası ekleyin
312
+ - Kullanım örnekleri verin
313
+ - API dokümantasyonu ekleyin
314
+
315
+ ### 4. Hata Yönetimi
316
+ - Uygun hata mesajları verin
317
+ - Graceful degradation sağlayın
318
+ - Log dosyaları kullanın
319
+
320
+ ### 5. Güvenlik
321
+ - Hassas bilgileri kodlamayın
322
+ - Input validation yapın
323
+ - Güvenli dosya işlemleri kullanın
324
+
325
+ ### 6. Performans
326
+ - Gereksiz bağımlılıklardan kaçının
327
+ - Hızlı başlangıç sağlayın
328
+ - Bellek kullanımını optimize edin
329
+
330
+ ## 🆘 Yardım
331
+
332
+ ### Hata Ayıklama
333
+
334
+ ```bash
335
+ # Sistem durumunu kontrol et
336
+ clapp doctor
337
+
338
+ # Ortam kontrolü
339
+ clapp check-env
340
+
341
+ # Uygulama konumunu bul
342
+ clapp where my-app
343
+ ```
344
+
345
+ ### Destek
346
+
347
+ - GitHub Issues: [clapp repository](https://github.com/mburakmmm/clapp)
348
+ - Dokümantasyon: Bu rehber
349
+ - Örnekler: `templates/` klasörü
350
+
351
+ ## 📝 Örnekler
352
+
353
+ Daha fazla örnek için `templates/` klasörünü inceleyin:
354
+
355
+ - `templates/python/` - Python örnekleri
356
+ - `templates/lua/` - Lua örnekleri
357
+ - `templates/dart/` - Dart örnekleri
358
+ - `templates/go/` - Go örnekleri
359
+ - `templates/rust/` - Rust örnekleri
360
+
361
+ Her örnek tam çalışan bir uygulama içerir ve kopyalanıp değiştirilebilir.
install_command.py CHANGED
@@ -18,6 +18,7 @@ from pathlib import Path
18
18
  from typing import Tuple, Optional, Dict, Any
19
19
 
20
20
  from manifest_validator import validate_manifest_verbose
21
+ from progress_utils import download_with_progress, extract_with_progress, show_success_message, show_error_message
21
22
 
22
23
  def get_apps_directory() -> str:
23
24
  """Uygulamaların kurulacağı dizini döndürür"""
@@ -91,21 +92,18 @@ def download_app_from_github(app_info: Dict[str, Any], temp_dir: str) -> Tuple[b
91
92
  else:
92
93
  return False, f"Desteklenmeyen repo URL: {repo_url}"
93
94
 
94
- print(f"📥 İndiriliyor: {zip_url}")
95
+ # Progress bar ile indir
96
+ zip_path = os.path.join(temp_dir, "repo.zip")
97
+ success = download_with_progress(zip_url, zip_path, f"📦 {app_name} indiriliyor")
95
98
 
96
- # Zip dosyasını indir
97
- response = requests.get(zip_url, timeout=30)
98
- if response.status_code != 200:
99
- return False, f"İndirme hatası: {response.status_code}"
99
+ if not success:
100
+ return False, "İndirme başarısız"
100
101
 
101
- # Zip dosyasını geçici klasöre kaydet
102
- zip_path = os.path.join(temp_dir, "repo.zip")
103
- with open(zip_path, 'wb') as f:
104
- f.write(response.content)
102
+ # Progress bar ile çıkar
103
+ success = extract_with_progress(zip_path, temp_dir, f"📦 {app_name} çıkarılıyor")
105
104
 
106
- # Zip'i
107
- with zipfile.ZipFile(zip_path, 'r') as zip_ref:
108
- zip_ref.extractall(temp_dir)
105
+ if not success:
106
+ return False, "Çıkarma başarısız"
109
107
 
110
108
  # Çıkarılan klasörü bul (genellikle repo-main formatında)
111
109
  extracted_folders = [d for d in os.listdir(temp_dir) if os.path.isdir(os.path.join(temp_dir, d))]
@@ -156,6 +154,8 @@ def install_app_locally(app_name: str, source_path: str) -> Tuple[bool, str]:
156
154
  shutil.rmtree(target_path)
157
155
  return False, f"Manifest doğrulama hatası: {errors}"
158
156
 
157
+ show_success_message(f"'{app_name}' başarıyla yüklendi!")
158
+
159
159
  # Bağımlılık çözümleme entegrasyonu
160
160
  print("5️⃣ Bağımlılıklar kontrol ediliyor...")
161
161
  from dependency_resolver import check_and_install_python_dependencies, check_and_install_lua_dependencies, check_engine_availability
installer.py CHANGED
@@ -6,6 +6,7 @@ import shutil
6
6
  import json
7
7
  from manifest_validator import validate_manifest_verbose
8
8
  from package_registry import app_exists
9
+ from progress_utils import download_with_progress, extract_with_progress, copy_with_progress, show_success_message, show_error_message
9
10
 
10
11
  def find_app_folder(extract_path, app_name):
11
12
  """
@@ -81,6 +82,8 @@ def install_package(source, force=False):
81
82
  if os.path.exists(target_dir):
82
83
  shutil.rmtree(target_dir)
83
84
  shutil.copytree(app_real_folder, target_dir)
85
+
86
+ show_success_message(f"'{app_name}' başarıyla yüklendi!")
84
87
  return True, f"✅ '{app_name}' başarıyla yüklendi!"
85
88
  except Exception as e:
86
89
  return False, f"Yükleme hatası: {e}"
@@ -100,8 +103,6 @@ def download_package(url, temp_dir):
100
103
  str or None: İndirilen dosyanın yolu veya None
101
104
  """
102
105
  try:
103
- print(f"Paket indiriliyor: {url}")
104
-
105
106
  # Dosya adını URL'den çıkar
106
107
  filename = os.path.basename(url)
107
108
  if not filename.endswith('.zip'):
@@ -109,14 +110,16 @@ def download_package(url, temp_dir):
109
110
 
110
111
  zip_path = os.path.join(temp_dir, filename)
111
112
 
112
- # Dosyayı indir
113
- urllib.request.urlretrieve(url, zip_path)
113
+ # Progress bar ile indir
114
+ success = download_with_progress(url, zip_path, f"📦 {filename} indiriliyor")
114
115
 
115
- print(f"✅ İndirme tamamlandı: {filename}")
116
- return zip_path
116
+ if success:
117
+ return zip_path
118
+ else:
119
+ return None
117
120
 
118
121
  except Exception as e:
119
- print(f"İndirme hatası: {e}")
122
+ show_error_message(f"İndirme hatası: {e}")
120
123
  return None
121
124
 
122
125
  def extract_package(zip_path, extract_path):
@@ -134,12 +137,14 @@ def extract_package(zip_path, extract_path):
134
137
  # Çıkarma dizinini oluştur
135
138
  os.makedirs(extract_path, exist_ok=True)
136
139
 
137
- # Zip dosyasını ve çıkar
138
- with zipfile.ZipFile(zip_path, 'r') as zip_ref:
139
- zip_ref.extractall(extract_path)
140
+ # Progress bar ile çıkar
141
+ filename = os.path.basename(zip_path)
142
+ success = extract_with_progress(zip_path, extract_path, f"📦 {filename} çıkarılıyor")
140
143
 
141
- print(f"✅ Paket çıkarıldı: {extract_path}")
142
- return True, "Paket başarıyla çıkarıldı"
144
+ if success:
145
+ return True, "Paket başarıyla çıkarıldı"
146
+ else:
147
+ return False, "Çıkarma hatası"
143
148
 
144
149
  except zipfile.BadZipFile:
145
150
  return False, "Geçersiz zip dosyası"
@@ -259,6 +264,7 @@ def install_from_directory(source_dir, force=False):
259
264
  # Dosyaları kopyala
260
265
  shutil.copytree(source_dir, target_dir)
261
266
 
267
+ show_success_message(f"'{app_name}' başarıyla yüklendi!")
262
268
  return True, f"✅ '{app_name}' başarıyla yüklendi!"
263
269
 
264
270
  except Exception as e:
main.py CHANGED
@@ -33,7 +33,7 @@ from where_command import locate_app_path, list_all_app_locations
33
33
  from version_command import print_version, print_detailed_version
34
34
 
35
35
  # Yeni güvenlik ve performans modülleri
36
- from package_signing import sign_package_file, verify_package_file, check_package_security
36
+ from package_signing import check_package_security
37
37
  from version_manager import check_app_updates, get_app_latest_version, increment_app_version
38
38
  from cache_manager import get_cache_stats, clear_all_caches, download_packages_parallel
39
39
  from smart_search import search_packages, get_search_suggestions, get_search_analytics, clear_search_history
@@ -52,6 +52,9 @@ from dependency_resolver import (
52
52
  handle_dependency_tree
53
53
  )
54
54
 
55
+ # Yeni uygulama oluşturma komutu
56
+ from new_command import handle_new_command
57
+
55
58
  def main():
56
59
  """Ana CLI fonksiyonu"""
57
60
 
@@ -69,6 +72,7 @@ def main():
69
72
  clapp list # Yüklü uygulamaları listele
70
73
  clapp run hello-python # hello-python uygulamasını çalıştır
71
74
  clapp info hello-python # Uygulama bilgilerini göster
75
+ clapp new python my-app # Yeni Python uygulaması oluştur
72
76
 
73
77
  🔧 Yönetim Komutları:
74
78
  clapp install app.zip # ZIP dosyasından uygulama yükle
@@ -228,6 +232,13 @@ def main():
228
232
  dep_tree_parser = dependency_subparsers.add_parser('tree', help='Bağımlılık ağacı')
229
233
  dep_tree_parser.add_argument('app_name', help='Uygulama adı')
230
234
 
235
+ # new komutu (yeni)
236
+ new_parser = subparsers.add_parser('new', help='Yeni uygulama oluştur')
237
+ new_parser.add_argument('language', nargs='?', help='Programlama dili')
238
+ new_parser.add_argument('app_name', nargs='?', help='Uygulama adı')
239
+ new_parser.add_argument('--list', action='store_true', help='Mevcut şablonları listele')
240
+ new_parser.add_argument('--target-dir', help='Hedef dizin (opsiyonel)')
241
+
231
242
  # Argümanları parse et
232
243
  args = parser.parse_args()
233
244
 
@@ -376,22 +387,17 @@ def main():
376
387
  print("❌ Geçersiz dependency komutu")
377
388
  sys.exit(1)
378
389
 
390
+ elif args.command == 'new':
391
+ # Yeni uygulama oluşturma komutu
392
+ success, message = handle_new_command(args)
393
+ if success:
394
+ print(message)
395
+ else:
396
+ print(f"❌ {message}")
397
+ sys.exit(1)
398
+
379
399
  elif args.command == 'security':
380
- if args.action == 'sign':
381
- success, message = sign_package_file(args.package_path)
382
- if success:
383
- print(f"✅ {message}")
384
- else:
385
- print(f"❌ {message}")
386
- sys.exit(1)
387
-
388
- elif args.action == 'verify':
389
- signature_path = args.signature or args.package_path.replace('.zip', '.sig')
390
- success, message = verify_package_file(args.package_path, signature_path)
391
- print(f"{'✅' if success else '❌'} {message}")
392
- sys.exit(0 if success else 1)
393
-
394
- elif args.action == 'check':
400
+ if args.action == 'check':
395
401
  results = check_package_security(args.package_path)
396
402
  print("🔒 Paket Güvenlik Kontrolü")
397
403
  print("=" * 40)
@@ -402,6 +408,9 @@ def main():
402
408
  print("\n⚠️ Uyarılar:")
403
409
  for warning in results['warnings']:
404
410
  print(f" - {warning}")
411
+ else:
412
+ print("❌ İmzalama özelliği geçici olarak devre dışı")
413
+ sys.exit(1)
405
414
 
406
415
  elif args.command == 'update':
407
416
  if args.action == 'check':
manifest_schema.py CHANGED
@@ -42,7 +42,11 @@ def validate_manifest(manifest):
42
42
  # Opsiyonel alanlar
43
43
  optional_fields = {
44
44
  'description': str,
45
- 'dependencies': list
45
+ 'dependencies': list,
46
+ 'author': str,
47
+ 'license': str,
48
+ 'tags': list,
49
+ 'category': str
46
50
  }
47
51
 
48
52
  # Gerekli alanları kontrol et
@@ -52,9 +56,16 @@ def validate_manifest(manifest):
52
56
  if not isinstance(manifest[field], expected_type):
53
57
  return False
54
58
 
55
- # Dil kontrolü
56
- if manifest['language'] not in ['python', 'lua']:
57
- return False
59
+ # Dil kontrolü - package_runner'dan desteklenen dilleri al
60
+ try:
61
+ from package_runner import get_supported_languages
62
+ supported_languages = get_supported_languages()
63
+ if manifest['language'] not in supported_languages:
64
+ return False
65
+ except ImportError:
66
+ # Fallback: Temel diller
67
+ if manifest['language'] not in ['python', 'lua', 'dart', 'go', 'rust', 'node', 'bash', 'perl', 'ruby', 'php']:
68
+ return False
58
69
 
59
70
  # Opsiyonel alanları kontrol et (varsa)
60
71
  for field, expected_type in optional_fields.items():
@@ -79,6 +90,10 @@ def get_schema():
79
90
  },
80
91
  "optional_fields": {
81
92
  "description": "string",
82
- "dependencies": "list"
93
+ "dependencies": "list",
94
+ "author": "string",
95
+ "license": "string",
96
+ "tags": "list",
97
+ "category": "string"
83
98
  }
84
99
  }
manifest_validator.py CHANGED
@@ -39,8 +39,8 @@ def validate_manifest_verbose(manifest):
39
39
  elif field == "language":
40
40
  if not isinstance(value, str):
41
41
  errors.append(f"'{field}' alanı string olmalı")
42
- elif value.lower() not in ["python", "lua"]:
43
- errors.append(f"'{field}' alanı 'python' veya 'lua' olmalı, '{value}' geçersiz")
42
+ elif value.lower() not in ["python", "lua", "dart", "go", "rust", "node", "bash", "perl", "ruby", "php"]:
43
+ errors.append(f"'{field}' alanı desteklenen bir dil olmalı, '{value}' geçersiz")
44
44
  elif field == "entry":
45
45
  if not isinstance(value, str) or not value.strip():
46
46
  errors.append(f"'{field}' alanı boş olmayan bir string olmalı")
@@ -61,7 +61,7 @@ def validate_manifest_verbose(manifest):
61
61
  errors.append(f"'dependencies[{i}]' boş olmayan bir string olmalı")
62
62
 
63
63
  # Bilinmeyen alanları kontrol et
64
- known_fields = set(required_fields.keys()) | {"description", "dependencies"}
64
+ known_fields = set(required_fields.keys()) | {"description", "dependencies", "author", "license", "tags", "category"}
65
65
  for field in manifest.keys():
66
66
  if field not in known_fields:
67
67
  errors.append(f"Bilinmeyen alan: '{field}' (göz ardı edilecek)")