create-prisma-php-app 4.0.0-alpha.1 → 4.0.0-alpha.10

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 (36) hide show
  1. package/dist/bootstrap.php +10 -10
  2. package/dist/index.js +351 -424
  3. package/dist/settings/files-list.json +1 -1
  4. package/dist/settings/restart-websocket.bat +1 -1
  5. package/dist/settings/restart-websocket.ts +9 -2
  6. package/dist/src/Lib/AI/ChatGPTClient.php +147 -0
  7. package/dist/src/Lib/Auth/Auth.php +544 -0
  8. package/dist/src/Lib/Auth/AuthConfig.php +89 -0
  9. package/dist/src/Lib/CacheHandler.php +121 -0
  10. package/dist/src/Lib/ErrorHandler.php +322 -0
  11. package/dist/src/Lib/FileManager/UploadFile.php +383 -0
  12. package/dist/src/Lib/Headers/Boom.php +208 -0
  13. package/dist/src/Lib/IncludeTracker.php +59 -0
  14. package/dist/src/Lib/MainLayout.php +215 -0
  15. package/dist/src/Lib/Middleware/AuthMiddleware.php +154 -0
  16. package/dist/src/Lib/PHPMailer/Mailer.php +169 -0
  17. package/dist/src/Lib/PHPX/Exceptions/ComponentValidationException.php +49 -0
  18. package/dist/src/Lib/PHPX/IPHPX.php +22 -0
  19. package/dist/src/Lib/PHPX/PHPX.php +173 -0
  20. package/dist/src/Lib/PHPX/TemplateCompiler.php +584 -0
  21. package/dist/src/Lib/PHPX/TwMerge.php +195 -0
  22. package/dist/src/Lib/PHPX/TypeCoercer.php +490 -0
  23. package/dist/src/Lib/PartialRenderer.php +40 -0
  24. package/dist/src/Lib/PrismaPHPSettings.php +181 -0
  25. package/dist/src/Lib/Request.php +476 -0
  26. package/dist/src/Lib/Set.php +102 -0
  27. package/dist/src/Lib/StateManager.php +127 -0
  28. package/dist/src/Lib/Validator.php +738 -0
  29. package/dist/src/{Websocket → Lib/Websocket}/ConnectionManager.php +1 -1
  30. package/dist/{websocket-server.php → src/Lib/Websocket/websocket-server.php} +7 -2
  31. package/dist/src/app/assets/images/prisma-php-black.svg +5 -5
  32. package/dist/src/app/error.php +1 -1
  33. package/dist/src/app/index.php +1 -1
  34. package/dist/src/app/js/index.js +1 -1
  35. package/dist/src/app/layout.php +2 -2
  36. package/package.json +1 -1
@@ -1 +1 @@
1
- []
1
+ []
@@ -1,7 +1,7 @@
1
1
  @echo off
2
2
  set PORT=8080
3
3
  set "PHP_PATH=php"
4
- set "SERVER_SCRIPT_PATH=websocket-server.php"
4
+ set "SERVER_SCRIPT_PATH= src\Lib\Websocket\websocket-server.php"
5
5
 
6
6
  echo [INFO] Checking for processes using port %PORT%...
7
7
  netstat -aon | findstr :%PORT%
@@ -6,7 +6,14 @@ import { getFileMeta } from "./utils.js";
6
6
  const { __dirname } = getFileMeta();
7
7
 
8
8
  const phpPath = "php";
9
- const serverScriptPath = join(__dirname, "..", "websocket-server.php");
9
+ const serverScriptPath = join(
10
+ __dirname,
11
+ "..",
12
+ "src",
13
+ "Lib",
14
+ "Websocket",
15
+ "websocket-server.php"
16
+ );
10
17
 
11
18
  let serverProcess: ChildProcess | null = null;
12
19
 
@@ -41,6 +48,6 @@ chokidar
41
48
  .watch(join(__dirname, "..", "src", "Websocket", "**", "*"))
42
49
  .on("change", (path: string) => {
43
50
  const fileChanged = path.split("\\").pop();
44
- console.log(`File changed: src/Websocket/${fileChanged}`);
51
+ console.log(`File changed: src/Lib/Websocket/${fileChanged}`);
45
52
  restartServer();
46
53
  });
@@ -0,0 +1,147 @@
1
+ <?php
2
+
3
+ declare(strict_types=1);
4
+
5
+ namespace Lib\AI;
6
+
7
+ use GuzzleHttp\Client;
8
+ use GuzzleHttp\Exception\RequestException;
9
+ use Lib\Validator;
10
+ use RuntimeException;
11
+
12
+ class ChatGPTClient
13
+ {
14
+ private Client $client;
15
+ private string $apiUrl = '';
16
+ private string $apiKey = '';
17
+ private array $cache = [];
18
+
19
+ public function __construct(?Client $client = null)
20
+ {
21
+ // Initialize the Guzzle HTTP client, allowing for dependency injection
22
+ $this->client = $client ?: new Client();
23
+
24
+ // API URL for chat completions
25
+ $this->apiUrl = 'https://api.openai.com/v1/chat/completions';
26
+
27
+ // Get the API key from environment variables (keep this private and secure)
28
+ $this->apiKey = $_ENV['CHATGPT_API_KEY'];
29
+ }
30
+
31
+ /**
32
+ * Determines the appropriate model based on internal logic.
33
+ *
34
+ * @param array $conversationHistory The conversation history array.
35
+ * @return string The model name to be used.
36
+ */
37
+ protected function determineModel(array $conversationHistory): string
38
+ {
39
+ $messageCount = count($conversationHistory);
40
+ $totalTokens = array_reduce(
41
+ $conversationHistory,
42
+ fn($carry, $item) => $carry + str_word_count($item['content'] ?? ''),
43
+ 0
44
+ );
45
+
46
+ // If the conversation is long or complex, use a model with more tokens
47
+ if ($totalTokens > 4000 || $messageCount > 10) {
48
+ return 'gpt-3.5-turbo-16k'; // Use the model with a larger token limit
49
+ }
50
+
51
+ // Default to the standard model for shorter conversations
52
+ return 'gpt-3.5-turbo';
53
+ }
54
+
55
+ /**
56
+ * Formats the conversation history to ensure it is valid.
57
+ *
58
+ * @param array $conversationHistory The conversation history array.
59
+ * @return array The formatted conversation history.
60
+ */
61
+ protected function formatConversationHistory(array $conversationHistory): array
62
+ {
63
+ $formattedHistory = [];
64
+ foreach ($conversationHistory as $message) {
65
+ if (is_array($message) && isset($message['role'], $message['content']) && Validator::string($message['content'])) {
66
+ $formattedHistory[] = $message;
67
+ } else {
68
+ $formattedHistory[] = ['role' => 'user', 'content' => (string) $message];
69
+ }
70
+ }
71
+ return $formattedHistory;
72
+ }
73
+
74
+ /**
75
+ * Sends a message to the OpenAI API and returns the AI's response as HTML.
76
+ *
77
+ * @param array $conversationHistory The conversation history array containing previous messages.
78
+ * @param string $userMessage The new user message to add to the conversation.
79
+ * @return string The AI-generated HTML response.
80
+ *
81
+ * @throws \InvalidArgumentException If a message in the conversation history is not valid.
82
+ * @throws RuntimeException If the API request fails or returns an unexpected format.
83
+ */
84
+ public function sendMessage(array $conversationHistory, string $userMessage): string
85
+ {
86
+ if (!Validator::string($userMessage)) {
87
+ throw new \InvalidArgumentException("Invalid user message: must be a string.");
88
+ }
89
+
90
+ // Optional: Convert emojis or special patterns in the message
91
+ $userMessage = Validator::emojis($userMessage);
92
+
93
+ // Prepare the conversation, including a system-level instruction to return valid HTML
94
+ $systemInstruction = [
95
+ 'role' => 'system',
96
+ 'content' => 'You are ChatGPT. Please provide your response in valid HTML format.'
97
+ ];
98
+
99
+ // Format existing history, then prepend the system message
100
+ $formattedHistory = $this->formatConversationHistory($conversationHistory);
101
+ array_unshift($formattedHistory, $systemInstruction);
102
+
103
+ // Append the new user message
104
+ $formattedHistory[] = ['role' => 'user', 'content' => $userMessage];
105
+
106
+ // Check cache
107
+ $cacheKey = md5(serialize($formattedHistory));
108
+ if (isset($this->cache[$cacheKey])) {
109
+ return $this->cache[$cacheKey];
110
+ }
111
+
112
+ // Determine the appropriate model to use
113
+ $model = $this->determineModel($formattedHistory);
114
+
115
+ try {
116
+ // Sending a POST request to the AI API
117
+ $response = $this->client->request('POST', $this->apiUrl, [
118
+ 'headers' => [
119
+ 'Authorization' => 'Bearer ' . $this->apiKey,
120
+ 'Content-Type' => 'application/json',
121
+ ],
122
+ 'json' => [
123
+ 'model' => $model,
124
+ 'messages' => $formattedHistory,
125
+ 'max_tokens' => 500,
126
+ ],
127
+ ]);
128
+
129
+ $responseBody = $response->getBody();
130
+ $responseContent = json_decode((string) $responseBody, true);
131
+
132
+ // Check if response is in expected format
133
+ if (isset($responseContent['choices'][0]['message']['content'])) {
134
+ $aiMessage = $responseContent['choices'][0]['message']['content'];
135
+
136
+ // Cache the result
137
+ $this->cache[$cacheKey] = $aiMessage;
138
+
139
+ return $aiMessage;
140
+ }
141
+
142
+ throw new RuntimeException('Unexpected API response format.');
143
+ } catch (RequestException $e) {
144
+ throw new RuntimeException("API request failed: " . $e->getMessage(), 0, $e);
145
+ }
146
+ }
147
+ }