@artilingo/artiframe-cli 1.0.9 → 1.1.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 (35) hide show
  1. package/README.md +1 -1
  2. package/bin/artiframe.php +1 -1
  3. package/core-stubs/app/Database.php +1 -1
  4. package/core-stubs/app/DotEnv.php +1 -1
  5. package/core-stubs/app/R2Manager.php +1 -1
  6. package/core-stubs/bin/SystemMethod.php +292 -16
  7. package/core-stubs/bin/ViewMethod.php +146 -37
  8. package/core-stubs/docs/de.html +4419 -955
  9. package/core-stubs/docs/en.html +4419 -956
  10. package/core-stubs/docs/es.html +4419 -951
  11. package/core-stubs/docs/fr.html +4101 -536
  12. package/core-stubs/docs/tr.html +4978 -955
  13. package/core-stubs/stubs/service/image.stub +334 -0
  14. package/core-stubs/stubs/service/iyzico.stub +637 -0
  15. package/core-stubs/stubs/service/jwt.stub +312 -0
  16. package/core-stubs/stubs/service/pusher.stub +232 -0
  17. package/core-stubs/stubs/service/redis.stub +361 -0
  18. package/core-stubs/stubs/service/s3.stub +377 -0
  19. package/core-stubs/stubs/service/sentry.stub +139 -0
  20. package/core-stubs/stubs/service/stripe.stub +526 -0
  21. package/core-stubs/stubs/service/twilio.stub +361 -0
  22. package/package.json +4 -4
  23. package/src/App.php +69 -0
  24. package/src/Commands/AddCommand.php +392 -0
  25. package/src/Commands/GoCommand.php +48 -0
  26. package/src/Commands/ListCommand.php +67 -0
  27. package/src/Commands/NewProjectCommand.php +184 -30
  28. package/src/Commands/RemoveCommand.php +121 -0
  29. package/src/Commands/ServeCommand.php +71 -0
  30. package/src/Commands/ShowCommand.php +24 -0
  31. package/src/Lang/de.php +56 -0
  32. package/src/Lang/en.php +56 -0
  33. package/src/Lang/es.php +56 -0
  34. package/src/Lang/fr.php +56 -0
  35. package/src/Lang/tr.php +56 -0
@@ -0,0 +1,361 @@
1
+ <?php
2
+
3
+ namespace Service;
4
+
5
+ use Twilio\Rest\Client;
6
+
7
+ /**
8
+ * Twilio Communications Service
9
+ *
10
+ * Provides a simplified interface for Twilio's messaging, voice,
11
+ * and verification APIs using the twilio/sdk. All configuration
12
+ * is read from $_ENV.
13
+ *
14
+ * Required environment variables:
15
+ * TWILIO_SID — Your Twilio Account SID
16
+ * TWILIO_AUTH_TOKEN — Your Twilio Auth Token
17
+ * TWILIO_FROM_NUMBER — Default "from" phone number (E.164 format, e.g., +15551234567)
18
+ *
19
+ * Optional environment variables:
20
+ * TWILIO_VERIFY_SID — Verify Service SID (required for verifyStart/verifyCheck)
21
+ *
22
+ * @package Service
23
+ */
24
+ class TwilioService
25
+ {
26
+ /**
27
+ * The Twilio REST API client instance.
28
+ *
29
+ * @var \Twilio\Rest\Client
30
+ */
31
+ private Client $client;
32
+
33
+ /**
34
+ * The default "from" phone number in E.164 format.
35
+ *
36
+ * @var string
37
+ */
38
+ private string $fromNumber;
39
+
40
+ /**
41
+ * Create a new TwilioService instance.
42
+ *
43
+ * Initializes the Twilio REST client using account credentials
44
+ * from environment variables.
45
+ *
46
+ * @throws \Twilio\Exceptions\ConfigurationException If SID or Auth Token are invalid
47
+ */
48
+ public function __construct()
49
+ {
50
+ $this->client = new Client(
51
+ $_ENV['TWILIO_SID'],
52
+ $_ENV['TWILIO_AUTH_TOKEN']
53
+ );
54
+ $this->fromNumber = $_ENV['TWILIO_FROM_NUMBER'];
55
+ }
56
+
57
+ /**
58
+ * Send an SMS message.
59
+ *
60
+ * Sends a text message to the specified phone number using the
61
+ * configured "from" number.
62
+ *
63
+ * @param string $to Recipient phone number in E.164 format (e.g., +905551234567)
64
+ * @param string $message The SMS body text (max 1600 characters)
65
+ * @return array Result with keys: 'status', 'sid', 'message'
66
+ * On error: 'status' => 'error', 'message' => error description
67
+ */
68
+ public function sendSms(string $to, string $message): array
69
+ {
70
+ try {
71
+ $msg = $this->client->messages->create($to, [
72
+ 'from' => $this->fromNumber,
73
+ 'body' => $message,
74
+ ]);
75
+
76
+ return [
77
+ 'status' => $msg->status,
78
+ 'sid' => $msg->sid,
79
+ 'message' => 'SMS sent successfully',
80
+ ];
81
+ } catch (\Exception $e) {
82
+ return [
83
+ 'status' => 'error',
84
+ 'sid' => null,
85
+ 'message' => $e->getMessage(),
86
+ ];
87
+ }
88
+ }
89
+
90
+ /**
91
+ * Send a WhatsApp message.
92
+ *
93
+ * Sends a message via the Twilio WhatsApp Business API.
94
+ * Both the sender and recipient numbers are prefixed with 'whatsapp:'.
95
+ *
96
+ * Note: Your Twilio number must be approved for WhatsApp messaging,
97
+ * or you must use the Twilio Sandbox for WhatsApp during development.
98
+ *
99
+ * @param string $to Recipient phone number in E.164 format (e.g., +905551234567)
100
+ * @param string $message The message body text
101
+ * @return array Result with keys: 'status', 'sid', 'message'
102
+ */
103
+ public function sendWhatsApp(string $to, string $message): array
104
+ {
105
+ try {
106
+ $msg = $this->client->messages->create("whatsapp:{$to}", [
107
+ 'from' => "whatsapp:{$this->fromNumber}",
108
+ 'body' => $message,
109
+ ]);
110
+
111
+ return [
112
+ 'status' => $msg->status,
113
+ 'sid' => $msg->sid,
114
+ 'message' => 'WhatsApp message sent successfully',
115
+ ];
116
+ } catch (\Exception $e) {
117
+ return [
118
+ 'status' => 'error',
119
+ 'sid' => null,
120
+ 'message' => $e->getMessage(),
121
+ ];
122
+ }
123
+ }
124
+
125
+ /**
126
+ * Initiate a voice call.
127
+ *
128
+ * Places an outbound call to the specified number. The call behavior
129
+ * is defined by the TwiML document at the given URL. The TwiML URL
130
+ * should return instructions like <Say>, <Play>, <Gather>, etc.
131
+ *
132
+ * @param string $to Recipient phone number in E.164 format
133
+ * @param string $twimlUrl URL pointing to a TwiML document that controls the call
134
+ * @return array Result with keys: 'status', 'sid', 'message'
135
+ */
136
+ public function call(string $to, string $twimlUrl): array
137
+ {
138
+ try {
139
+ $call = $this->client->calls->create($to, $this->fromNumber, [
140
+ 'url' => $twimlUrl,
141
+ ]);
142
+
143
+ return [
144
+ 'status' => $call->status,
145
+ 'sid' => $call->sid,
146
+ 'message' => 'Call initiated successfully',
147
+ ];
148
+ } catch (\Exception $e) {
149
+ return [
150
+ 'status' => 'error',
151
+ 'sid' => null,
152
+ 'message' => $e->getMessage(),
153
+ ];
154
+ }
155
+ }
156
+
157
+ /**
158
+ * Start a phone number verification.
159
+ *
160
+ * Sends a verification code to the specified phone number using
161
+ * Twilio's Verify API. Supports SMS, voice call, and email channels.
162
+ *
163
+ * Requires the TWILIO_VERIFY_SID environment variable to be set
164
+ * with a valid Verify Service SID.
165
+ *
166
+ * @param string $to Phone number to verify in E.164 format
167
+ * @param string $channel Delivery channel: 'sms', 'call', or 'email' (default: 'sms')
168
+ * @return array Result with keys: 'status', 'sid', 'message'
169
+ * status will be 'pending' on success
170
+ */
171
+ public function verifyStart(string $to, string $channel = 'sms'): array
172
+ {
173
+ try {
174
+ $verifySid = $_ENV['TWILIO_VERIFY_SID'] ?? null;
175
+
176
+ if (!$verifySid) {
177
+ return [
178
+ 'status' => 'error',
179
+ 'sid' => null,
180
+ 'message' => 'TWILIO_VERIFY_SID environment variable is not set',
181
+ ];
182
+ }
183
+
184
+ $verification = $this->client->verify->v2
185
+ ->services($verifySid)
186
+ ->verifications
187
+ ->create($to, $channel);
188
+
189
+ return [
190
+ 'status' => $verification->status,
191
+ 'sid' => $verification->sid,
192
+ 'message' => 'Verification code sent successfully',
193
+ ];
194
+ } catch (\Exception $e) {
195
+ return [
196
+ 'status' => 'error',
197
+ 'sid' => null,
198
+ 'message' => $e->getMessage(),
199
+ ];
200
+ }
201
+ }
202
+
203
+ /**
204
+ * Check a verification code.
205
+ *
206
+ * Validates the code entered by the user against the one sent
207
+ * via verifyStart(). Returns 'approved' status on a successful match.
208
+ *
209
+ * Requires the TWILIO_VERIFY_SID environment variable to be set.
210
+ *
211
+ * @param string $to The phone number that was verified (E.164 format)
212
+ * @param string $code The verification code entered by the user
213
+ * @return array Result with keys: 'status', 'sid', 'message'
214
+ * status will be 'approved' on successful verification
215
+ */
216
+ public function verifyCheck(string $to, string $code): array
217
+ {
218
+ try {
219
+ $verifySid = $_ENV['TWILIO_VERIFY_SID'] ?? null;
220
+
221
+ if (!$verifySid) {
222
+ return [
223
+ 'status' => 'error',
224
+ 'sid' => null,
225
+ 'message' => 'TWILIO_VERIFY_SID environment variable is not set',
226
+ ];
227
+ }
228
+
229
+ $check = $this->client->verify->v2
230
+ ->services($verifySid)
231
+ ->verificationChecks
232
+ ->create([
233
+ 'to' => $to,
234
+ 'code' => $code,
235
+ ]);
236
+
237
+ return [
238
+ 'status' => $check->status,
239
+ 'sid' => $check->sid,
240
+ 'message' => $check->status === 'approved'
241
+ ? 'Verification successful'
242
+ : 'Verification failed — invalid code',
243
+ ];
244
+ } catch (\Exception $e) {
245
+ return [
246
+ 'status' => 'error',
247
+ 'sid' => null,
248
+ 'message' => $e->getMessage(),
249
+ ];
250
+ }
251
+ }
252
+
253
+ /**
254
+ * Get the delivery status of a specific message.
255
+ *
256
+ * Fetches the current status of a previously sent message
257
+ * by its unique SID.
258
+ *
259
+ * Possible statuses: queued, sending, sent, delivered, undelivered, failed
260
+ *
261
+ * @param string $messageSid The message SID (e.g., 'SMxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')
262
+ * @return array Result with keys: 'status', 'sid', 'to', 'from',
263
+ * 'date_sent', 'price', 'error_code', 'error_message'
264
+ */
265
+ public function getMessageStatus(string $messageSid): array
266
+ {
267
+ try {
268
+ $msg = $this->client->messages($messageSid)->fetch();
269
+
270
+ return [
271
+ 'status' => $msg->status,
272
+ 'sid' => $msg->sid,
273
+ 'to' => $msg->to,
274
+ 'from' => $msg->from,
275
+ 'date_sent' => $msg->dateSent ? $msg->dateSent->format('Y-m-d H:i:s') : null,
276
+ 'price' => $msg->price,
277
+ 'error_code' => $msg->errorCode,
278
+ 'error_message' => $msg->errorMessage,
279
+ ];
280
+ } catch (\Exception $e) {
281
+ return [
282
+ 'status' => 'error',
283
+ 'sid' => $messageSid,
284
+ 'message' => $e->getMessage(),
285
+ ];
286
+ }
287
+ }
288
+
289
+ /**
290
+ * List recent messages from your Twilio account.
291
+ *
292
+ * Retrieves the most recent messages ordered by date sent (descending).
293
+ * Each message includes its SID, status, direction, body preview,
294
+ * and timestamps.
295
+ *
296
+ * @param int $limit Maximum number of messages to return (default: 20, max: 1000)
297
+ * @return array List of message arrays with keys:
298
+ * 'sid', 'status', 'direction', 'from', 'to', 'body', 'date_sent'
299
+ */
300
+ public function listMessages(int $limit = 20): array
301
+ {
302
+ try {
303
+ $messages = $this->client->messages->read([], $limit);
304
+ $result = [];
305
+
306
+ foreach ($messages as $msg) {
307
+ $result[] = [
308
+ 'sid' => $msg->sid,
309
+ 'status' => $msg->status,
310
+ 'direction' => $msg->direction,
311
+ 'from' => $msg->from,
312
+ 'to' => $msg->to,
313
+ 'body' => $msg->body,
314
+ 'date_sent' => $msg->dateSent ? $msg->dateSent->format('Y-m-d H:i:s') : null,
315
+ ];
316
+ }
317
+
318
+ return $result;
319
+ } catch (\Exception $e) {
320
+ return [];
321
+ }
322
+ }
323
+
324
+ /**
325
+ * Send the same SMS message to multiple recipients.
326
+ *
327
+ * Iterates through the list of phone numbers and sends the
328
+ * message to each one individually. Returns a summary of
329
+ * successes and failures.
330
+ *
331
+ * @param array $recipients List of phone numbers in E.164 format
332
+ * @param string $message The SMS body text
333
+ * @return array Summary with keys:
334
+ * 'total', 'sent', 'failed', 'results' (per-recipient detail)
335
+ */
336
+ public function sendBulkSms(array $recipients, string $message): array
337
+ {
338
+ $results = [];
339
+ $sent = 0;
340
+ $failed = 0;
341
+
342
+ foreach ($recipients as $to) {
343
+ $result = $this->sendSms($to, $message);
344
+
345
+ if ($result['status'] !== 'error') {
346
+ $sent++;
347
+ } else {
348
+ $failed++;
349
+ }
350
+
351
+ $results[] = array_merge(['to' => $to], $result);
352
+ }
353
+
354
+ return [
355
+ 'total' => count($recipients),
356
+ 'sent' => $sent,
357
+ 'failed' => $failed,
358
+ 'results' => $results,
359
+ ];
360
+ }
361
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@artilingo/artiframe-cli",
3
- "version": "1.0.9",
3
+ "version": "1.1.0",
4
4
  "description": "ArtiFrame — Zero-dependency native PHP framework with a powerful multilingual CLI. Scaffold projects, generate views, APIs and classes instantly.",
5
5
  "main": "bin/artiframe.js",
6
6
  "bin": {
@@ -21,11 +21,11 @@
21
21
  ],
22
22
  "repository": {
23
23
  "type": "git",
24
- "url": "git+https://github.com/artilingo/artiframe.git"
24
+ "url": "git+https://github.com/utkuthecoder/artiframe-cli.git"
25
25
  },
26
- "homepage": "https://artiframe.org",
26
+ "homepage": "https://artiframe.artilingo.com",
27
27
  "bugs": {
28
- "url": "https://github.com/artilingo/artiframe/issues"
28
+ "url": "https://github.com/utkuthecoder/artiframe-cli/issues"
29
29
  },
30
30
  "keywords": [
31
31
  "php",
package/src/App.php CHANGED
@@ -171,6 +171,20 @@ class App
171
171
  private function routeCommand(string $commandName, array $commandArgs): void
172
172
  {
173
173
  switch ($commandName) {
174
+
175
+
176
+ case 'go':
177
+ (new \ArtiFrame\Cli\Commands\GoCommand($this->translator))->execute($commandArgs);
178
+ break;
179
+
180
+ case 'show':
181
+ (new \ArtiFrame\Cli\Commands\ShowCommand($this->translator))->execute($commandArgs);
182
+ break;
183
+
184
+ case 'list':
185
+ (new \ArtiFrame\Cli\Commands\ListCommand($this->translator))->execute($commandArgs);
186
+ break;
187
+
174
188
  case 'new':
175
189
  (new \ArtiFrame\Cli\Commands\NewProjectCommand($this->translator))->execute($commandArgs);
176
190
  break;
@@ -191,6 +205,20 @@ class App
191
205
  (new \ArtiFrame\Cli\Commands\LangCommand($this->translator))->execute($commandArgs);
192
206
  break;
193
207
 
208
+
209
+ case 'remove':
210
+ (new \ArtiFrame\Cli\Commands\RemoveCommand($this->translator))->execute($commandArgs);
211
+ break;
212
+
213
+
214
+ case 'serve':
215
+ (new \ArtiFrame\Cli\Commands\ServeCommand($this->translator))->execute($commandArgs);
216
+ break;
217
+
218
+ case 'add':
219
+ (new \ArtiFrame\Cli\Commands\AddCommand($this->translator))->execute($commandArgs);
220
+ break;
221
+
194
222
  case 'version':
195
223
  // Always routes to project version manager
196
224
  (new \ArtiFrame\Cli\Commands\VersionCommand($this->translator))->execute($commandArgs);
@@ -224,6 +252,25 @@ class App
224
252
  echo " " . $d . "─────────────────────────────────────────────────────────────" . $r . PHP_EOL;
225
253
  echo PHP_EOL;
226
254
 
255
+
256
+
257
+ // go
258
+ echo " " . $g . "go" . $r . " " . $y . "<dir>" . $r . PHP_EOL;
259
+ echo " " . $d . "│" . $r . " " . $t->get('HELP_GO_DESC') . PHP_EOL;
260
+ echo " " . $d . "├── " . $r . "Example: " . $lg . "go src" . $r . PHP_EOL;
261
+ echo " " . $d . "└── " . $r . "Example: " . $lg . "go back" . $r . PHP_EOL;
262
+ echo PHP_EOL;
263
+ // show
264
+ echo " " . $g . "show" . $r . PHP_EOL;
265
+ echo " " . $d . "│" . $r . " " . $t->get('HELP_SHOW_DESC') . PHP_EOL;
266
+ echo " " . $d . "└── " . $r . "Example: " . $lg . "show" . $r . PHP_EOL;
267
+ echo PHP_EOL;
268
+
269
+ // list
270
+ echo " " . $g . "list" . $r . PHP_EOL;
271
+ echo " " . $d . "│" . $r . " " . $t->get('HELP_LIST_DESC') . PHP_EOL;
272
+ echo " " . $d . "└── " . $r . "Example: " . $lg . "list" . $r . PHP_EOL;
273
+ echo PHP_EOL;
227
274
  // new
228
275
  echo " " . $g . "new" . $r . " " . $y . "<project-path>" . $r . PHP_EOL;
229
276
  echo " " . $d . "│" . $r . " " . $t->get('HELP_NEW_DESC') . PHP_EOL;
@@ -286,6 +333,28 @@ class App
286
333
  echo " " . $d . "└── " . $r . "Example: " . $lg . "lang en" . $r . $d . " (direct)" . $r . PHP_EOL;
287
334
  echo PHP_EOL;
288
335
 
336
+
337
+ // remove
338
+ echo " " . $g . "remove" . $r . " " . $y . "<file-path>" . $r . PHP_EOL;
339
+ echo " " . $d . "│" . $r . " " . $t->get('HELP_REMOVE_DESC') . PHP_EOL;
340
+ echo " " . $d . "├── " . $r . "Example: " . $lg . "remove public/pages/about.php" . $r . PHP_EOL;
341
+ echo " " . $d . "└── " . $r . "Example: " . $lg . "remove src/Auth/UserManager.php" . $r . PHP_EOL;
342
+ echo PHP_EOL;
343
+
344
+ // serve
345
+ echo " " . $g . "serve" . $r . " " . $y . "[port]" . $r . PHP_EOL;
346
+ echo " " . $d . "│" . $r . " " . $t->get('HELP_SERVE_DESC') . PHP_EOL;
347
+ echo " " . $d . "├── " . $r . "Example: " . $lg . "serve" . $r . $d . " (Port: 8000)" . $r . PHP_EOL;
348
+ echo " " . $d . "└── " . $r . "Example: " . $lg . "serve 8080" . $r . PHP_EOL;
349
+ echo PHP_EOL;
350
+ // add
351
+ echo " " . $g . "add" . $r . " " . $y . "<package>" . $r . PHP_EOL;
352
+ echo " " . $d . "│" . $r . " " . $t->get('HELP_ADD_DESC') . PHP_EOL;
353
+ echo " " . $d . "├── " . $r . "Example: " . $lg . "add iyzico" . $r . PHP_EOL;
354
+ echo " " . $d . "├── " . $r . "Example: " . $lg . "add phpmailer" . $r . PHP_EOL;
355
+ echo " " . $d . "└── " . $r . $lg . "add list" . $r . $d . " " . $t->get('HELP_ADD_LIST') . $r . PHP_EOL;
356
+ echo PHP_EOL;
357
+
289
358
  // help / exit
290
359
  echo " " . $d . "─────────────────────────────────────────────────────────────" . $r . PHP_EOL;
291
360
  echo " " . $g . "help" . $r . " " . $t->get('HELP_HELP_DESC') . PHP_EOL;