create-prisma-php-app 1.11.542 → 1.11.600

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.
package/composer.json CHANGED
@@ -17,6 +17,7 @@
17
17
  "php": "^8.1",
18
18
  "vlucas/phpdotenv": "^5.6@dev",
19
19
  "firebase/php-jwt": "dev-main",
20
- "phpmailer/phpmailer": "^6.9"
20
+ "phpmailer/phpmailer": "^6.9",
21
+ "guzzlehttp/guzzle": "7.8"
21
22
  }
22
23
  }
@@ -15,12 +15,10 @@ $dotenv->load();
15
15
 
16
16
  function determineContentToInclude()
17
17
  {
18
- $subject = $_SERVER["SCRIPT_NAME"];
19
- $dirname = dirname($subject);
20
- $requestUri = explode('?', $_SERVER['REQUEST_URI'], 2)[0];
21
- $requestUri = rtrim($requestUri, '/');
22
- $requestUri = str_replace($dirname, '', $requestUri);
23
- $uri = trim($requestUri, '/');
18
+ $scriptUrl = $_SERVER['REQUEST_URI'];
19
+ $scriptUrl = explode('?', $scriptUrl, 2)[0];
20
+ $uri = $_SERVER['SCRIPT_URL'] ?? uriExtractor($scriptUrl);
21
+ $uri = ltrim($uri, '/');
24
22
  $baseDir = APP_PATH;
25
23
  $includePath = '';
26
24
  $layoutsToInclude = [];
@@ -41,6 +39,16 @@ function determineContentToInclude()
41
39
  }
42
40
  }
43
41
 
42
+ if (empty($includePath)) {
43
+ $dynamicRoute = dynamicRoute($uri);
44
+ if ($dynamicRoute) {
45
+ $path = __DIR__ . $dynamicRoute;
46
+ if (file_exists($path)) {
47
+ $includePath = $path;
48
+ }
49
+ }
50
+ }
51
+
44
52
  $currentPath = $baseDir;
45
53
  $getGroupFolder = getGroupFolder($groupFolder);
46
54
  $modifiedUri = $uri;
@@ -69,51 +77,30 @@ function determineContentToInclude()
69
77
  return ['path' => $includePath, 'layouts' => $layoutsToInclude, 'uri' => $uri];
70
78
  }
71
79
 
72
- function checkForDuplicateRoutes()
80
+ function uriExtractor(string $scriptUrl): string
73
81
  {
74
- $routes = json_decode(file_get_contents(SETTINGS_PATH . "/files-list.json"), true);
75
-
76
- $normalizedRoutesMap = [];
77
- foreach ($routes as $route) {
78
- $routeWithoutGroups = preg_replace('/\(.*?\)/', '', $route);
79
- $routeTrimmed = ltrim($routeWithoutGroups, '.\\/');
80
- $routeTrimmed = preg_replace('#/{2,}#', '/', $routeTrimmed);
81
- $routeTrimmed = preg_replace('#\\\\{2,}#', '\\', $routeTrimmed);
82
- $routeNormalized = str_replace(['\\', '/'], DIRECTORY_SEPARATOR, $routeTrimmed);
83
- $normalizedRoutesMap[$routeNormalized][] = $route;
82
+ $prismaPHPSettings = json_decode(file_get_contents("prisma-php.json"), true);
83
+ $projectName = $prismaPHPSettings['projectName'] ?? '';
84
+ if (empty($projectName)) {
85
+ return "/";
84
86
  }
85
87
 
86
- $errorMessages = [];
87
- foreach ($normalizedRoutesMap as $normalizedRoute => $originalRoutes) {
88
- $basename = basename($normalizedRoute);
89
- if ($basename === 'layout.php') continue;
90
-
91
- if (count($originalRoutes) > 1 && strpos($normalizedRoute, DIRECTORY_SEPARATOR) !== false) {
92
- $directGroupMatchFound = false;
93
- foreach ($originalRoutes as $originalRoute) {
94
- if (preg_match('~^\\.\\/src\\/app[\\/\\\\]\\(.*?\\)[\\/\\\\].*?\\.php$~', $originalRoute, $matches)) {
95
- $directGroupMatchFound = true;
96
- }
97
- }
98
-
99
- if ($directGroupMatchFound) continue;
100
-
101
- $errorMessages[] = "Duplicate route found after normalization: " . $normalizedRoute;
102
-
103
- foreach ($originalRoutes as $originalRoute) {
104
- $errorMessages[] = "- Grouped original route: " . $originalRoute;
105
- }
88
+ $escapedIdentifier = preg_quote($projectName, '/');
89
+ $pattern = "/(?:.*$escapedIdentifier)(\/.*)$/";
90
+ if (preg_match($pattern, $scriptUrl, $matches)) {
91
+ if (!empty($matches[1])) {
92
+ $leftTrim = ltrim($matches[1], '/');
93
+ $rightTrim = rtrim($leftTrim, '/');
94
+ return "$rightTrim";
106
95
  }
107
96
  }
108
97
 
109
- if (!empty($errorMessages)) {
110
- $errorMessageString = implode("<br>", $errorMessages);
111
- modifyOutputLayoutForError($errorMessageString);
112
- }
98
+ return "/";
113
99
  }
114
100
 
115
101
  function writeRoutes()
116
102
  {
103
+ global $filesListRoutes;
117
104
  $directory = './src/app';
118
105
 
119
106
  if (is_dir($directory)) {
@@ -130,6 +117,10 @@ function writeRoutes()
130
117
  $jsonData = json_encode($filesList, JSON_PRETTY_PRINT);
131
118
  $jsonFileName = SETTINGS_PATH . '/files-list.json';
132
119
  @file_put_contents($jsonFileName, $jsonData);
120
+
121
+ if (file_exists($jsonFileName)) {
122
+ $filesListRoutes = json_decode(file_get_contents($jsonFileName), true);
123
+ }
133
124
  }
134
125
  }
135
126
 
@@ -152,6 +143,49 @@ function findGroupFolder($uri): string
152
143
  }
153
144
  }
154
145
 
146
+ function dynamicRoute($uri)
147
+ {
148
+ global $filesListRoutes;
149
+ global $dynamicRouteParams;
150
+ $uriMatch = null;
151
+ $normalizedUri = ltrim(str_replace('\\', '/', $uri), './');
152
+ $normalizedUriEdited = "src/app/$normalizedUri/route.php";
153
+ $uriSegments = explode('/', $normalizedUriEdited);
154
+ foreach ($filesListRoutes as $route) {
155
+ $normalizedRoute = trim(str_replace('\\', '/', $route), '.');
156
+ $routeSegments = explode('/', ltrim($normalizedRoute, '/'));
157
+ $singleDynamic = preg_match_all('/\[[^\]]+\]/', $normalizedRoute, $matches) === 1 && !strpos($normalizedRoute, '[...');
158
+ if ($singleDynamic) {
159
+ $segmentMatch = singleDynamicRoute($uriSegments, $routeSegments);
160
+ if (!empty($segmentMatch)) {
161
+ $trimSegmentMatch = trim($segmentMatch, '[]');
162
+ $dynamicRouteParams = [$trimSegmentMatch => $uriSegments[array_search($segmentMatch, $routeSegments)]];
163
+ $uriMatch = $normalizedRoute;
164
+ break;
165
+ }
166
+ } elseif (strpos($normalizedRoute, '[...') !== false) {
167
+ $cleanedRoute = preg_replace('/\[\.\.\..*?\].*/', '', $normalizedRoute);
168
+ if (strpos('/src/app/' . $normalizedUri, $cleanedRoute) === 0) {
169
+ if (strpos($normalizedRoute, 'route.php') !== false) {
170
+ $normalizedUriEdited = "/src/app/$normalizedUri";
171
+ $trimNormalizedUriEdited = str_replace($cleanedRoute, '', $normalizedUriEdited);
172
+ $explodedNormalizedUri = explode('/', $trimNormalizedUriEdited);
173
+ $pattern = '/\[\.\.\.(.*?)\]/';
174
+ if (preg_match($pattern, $normalizedRoute, $matches)) {
175
+ $contentWithinBrackets = $matches[1];
176
+ $dynamicRouteParams = [$contentWithinBrackets => $explodedNormalizedUri];
177
+ }
178
+
179
+ $uriMatch = $normalizedRoute;
180
+ break;
181
+ }
182
+ }
183
+ }
184
+ }
185
+
186
+ return $uriMatch;
187
+ }
188
+
155
189
  function isGroupIdentifier($segment): bool
156
190
  {
157
191
  return preg_match('/^\(.*\)$/', $segment);
@@ -159,15 +193,16 @@ function isGroupIdentifier($segment): bool
159
193
 
160
194
  function matchGroupFolder($constructedPath): ?string
161
195
  {
162
- $routes = json_decode(file_get_contents(SETTINGS_PATH . "/files-list.json"), true);
196
+ global $filesListRoutes;
163
197
  $bestMatch = null;
164
198
  $normalizedConstructedPath = ltrim(str_replace('\\', '/', $constructedPath), './');
165
199
 
166
200
  $routeFile = "/src/app/$normalizedConstructedPath/route.php";
167
201
  $indexFile = "/src/app/$normalizedConstructedPath/index.php";
168
202
 
169
- foreach ($routes as $route) {
203
+ foreach ($filesListRoutes as $route) {
170
204
  $normalizedRoute = trim(str_replace('\\', '/', $route), '.');
205
+
171
206
  $cleanedRoute = preg_replace('/\/\([^)]+\)/', '', $normalizedRoute);
172
207
  if ($cleanedRoute === $routeFile) {
173
208
  $bestMatch = $normalizedRoute;
@@ -192,10 +227,58 @@ function getGroupFolder($uri): string
192
227
  return "";
193
228
  }
194
229
 
195
- function redirect(string $url): void
230
+ function singleDynamicRoute($uriSegments, $routeSegments)
231
+ {
232
+ $segmentMatch = "";
233
+ if (count($routeSegments) != count($uriSegments)) {
234
+ return $segmentMatch;
235
+ }
236
+
237
+ foreach ($routeSegments as $index => $segment) {
238
+ if (preg_match('/^\[[^\]]+\]$/', $segment)) {
239
+ return "{$segment}";
240
+ } else {
241
+ if ($segment !== $uriSegments[$index]) {
242
+ return $segmentMatch;
243
+ }
244
+ }
245
+ }
246
+ return $segmentMatch;
247
+ }
248
+
249
+ function checkForDuplicateRoutes()
196
250
  {
197
- header("Location: $url");
198
- exit;
251
+ global $filesListRoutes;
252
+ $normalizedRoutesMap = [];
253
+ foreach ($filesListRoutes as $route) {
254
+ $routeWithoutGroups = preg_replace('/\(.*?\)/', '', $route);
255
+ $routeTrimmed = ltrim($routeWithoutGroups, '.\\/');
256
+ $routeTrimmed = preg_replace('#/{2,}#', '/', $routeTrimmed);
257
+ $routeTrimmed = preg_replace('#\\\\{2,}#', '\\', $routeTrimmed);
258
+ $routeNormalized = str_replace(['\\', '/'], DIRECTORY_SEPARATOR, $routeTrimmed);
259
+ $normalizedRoutesMap[$routeNormalized][] = $route;
260
+ }
261
+
262
+ $errorMessages = [];
263
+ foreach ($normalizedRoutesMap as $normalizedRoute => $originalRoutes) {
264
+ $basename = basename($normalizedRoute);
265
+ if ($basename === 'layout.php') continue;
266
+
267
+ if (count($originalRoutes) > 1 && strpos($normalizedRoute, DIRECTORY_SEPARATOR) !== false) {
268
+ if ($basename !== 'route.php' && $basename !== 'index.php') continue;
269
+
270
+ $errorMessages[] = "Duplicate route found after normalization: " . $normalizedRoute;
271
+
272
+ foreach ($originalRoutes as $originalRoute) {
273
+ $errorMessages[] = "- Grouped original route: " . $originalRoute;
274
+ }
275
+ }
276
+ }
277
+
278
+ if (!empty($errorMessages)) {
279
+ $errorMessageString = implode("<br>", $errorMessages);
280
+ modifyOutputLayoutForError($errorMessageString);
281
+ }
199
282
  }
200
283
 
201
284
  function setupErrorHandling(&$content)
@@ -221,19 +304,26 @@ function setupErrorHandling(&$content)
221
304
  }
222
305
 
223
306
  ob_start();
307
+ require_once SETTINGS_PATH . '/public-functions.php';
224
308
  require_once SETTINGS_PATH . '/request-methods.php';
225
309
  $metadataArray = require_once APP_PATH . '/metadata.php';
310
+ $filesListRoutes = [];
226
311
  $metadata = "";
312
+ $uri = "";
227
313
  $pathname = "";
314
+ $dynamicRouteParams = [];
228
315
  $content = "";
229
316
  $childContent = "";
230
317
 
231
318
  function containsChildContent($filePath)
232
319
  {
233
320
  $fileContent = file_get_contents($filePath);
234
- $pattern = '/<\?(?:php)?[^?]*\$childContent[^?]*\?>/is';
235
-
236
- if (preg_match($pattern, $fileContent)) {
321
+ if (
322
+ (strpos($fileContent, 'echo $childContent') === false &&
323
+ strpos($fileContent, 'echo $childContent;') === false) &&
324
+ (strpos($fileContent, '<?= $childContent ?>') === false) &&
325
+ (strpos($fileContent, '<?= $childContent; ?>') === false)
326
+ ) {
237
327
  return true;
238
328
  } else {
239
329
  return false;
@@ -243,8 +333,12 @@ function containsChildContent($filePath)
243
333
  function containsContent($filePath)
244
334
  {
245
335
  $fileContent = file_get_contents($filePath);
246
- $pattern = '/<\?(?:php\s+)?(?:=|echo|print)\s*\$content\s*;?\s*\?>/i';
247
- if (preg_match($pattern, $fileContent)) {
336
+ if (
337
+ (strpos($fileContent, 'echo $content') === false &&
338
+ strpos($fileContent, 'echo $content;') === false) &&
339
+ (strpos($fileContent, '<?= $content ?>') === false) &&
340
+ (strpos($fileContent, '<?= $content; ?>') === false)
341
+ ) {
248
342
  return true;
249
343
  } else {
250
344
  return false;
@@ -281,8 +375,10 @@ try {
281
375
  $parentLayoutPath = APP_PATH . '/layout.php';
282
376
  $isParentLayout = !empty($layoutsToInclude) && strpos($layoutsToInclude[0], 'src/app/layout.php') !== false;
283
377
 
284
- if (!containsContent($parentLayoutPath)) {
285
- $content .= "<div class='error'>The parent layout file does not contain &lt;?php echo \$content ?&gt; Or &lt;?= \$content ?&gt;<br>" . "<strong>$parentLayoutPath</strong></div>";
378
+ $isContentIncluded = false;
379
+ $isChildContentIncluded = false;
380
+ if (containsContent($parentLayoutPath)) {
381
+ $isContentIncluded = true;
286
382
  }
287
383
 
288
384
  ob_start();
@@ -293,13 +389,16 @@ try {
293
389
  $childContent = ob_get_clean();
294
390
  }
295
391
  foreach (array_reverse($layoutsToInclude) as $layoutPath) {
296
- ob_start();
297
- if ($parentLayoutPath === $layoutPath) continue;
392
+ if ($parentLayoutPath === $layoutPath) {
393
+ continue;
394
+ }
395
+
298
396
  if (containsChildContent($layoutPath)) {
299
- require_once $layoutPath;
300
- } else {
301
- $content .= "<div class='error'>The layout file does not contain &lt;?php echo \$childContent ?&gt; Or &lt;?= \$childContent ?&gt<br>" . "<strong>$layoutPath</strong></div>";
397
+ $isChildContentIncluded = true;
302
398
  }
399
+
400
+ ob_start();
401
+ require_once $layoutPath;
303
402
  $childContent = ob_get_clean();
304
403
  }
305
404
  } else {
@@ -314,11 +413,19 @@ try {
314
413
  $childContent = ob_get_clean();
315
414
  }
316
415
 
317
- $content .= $childContent;
318
-
319
- ob_start();
320
- require_once APP_PATH . '/layout.php';
321
- echo ob_get_clean();
416
+ if (!$isContentIncluded && !$isChildContentIncluded) {
417
+ $content .= $childContent;
418
+ ob_start();
419
+ require_once APP_PATH . '/layout.php';
420
+ } else {
421
+ if ($isContentIncluded) {
422
+ $content .= "<div class='error'>The parent layout file does not contain &lt;?php echo \$content; ?&gt; Or &lt;?= \$content ?&gt;<br>" . "<strong>$parentLayoutPath</strong></div>";
423
+ modifyOutputLayoutForError($content);
424
+ } else {
425
+ $content .= "<div class='error'>The layout file does not contain &lt;?php echo \$childContent; ?&gt; or &lt;?= \$childContent ?&gt;<br><strong>$layoutPath</strong></div>";
426
+ modifyOutputLayoutForError($content);
427
+ }
428
+ }
322
429
  } catch (Throwable $e) {
323
430
  $content = ob_get_clean();
324
431
  $content .= "<div class='error'>Unhandled Exception: " . htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8') . "</div>";
package/dist/index.js CHANGED
@@ -9,9 +9,9 @@ import https from "https";
9
9
  const __filename = fileURLToPath(import.meta.url);
10
10
  const __dirname = path.dirname(__filename);
11
11
  let updateAnswer = null;
12
- function bsConfigUrls(projectSettings) {
12
+ function bsConfigUrls(projectRootPath) {
13
13
  // Identify the base path dynamically up to and including 'htdocs'
14
- const htdocsIndex = projectSettings.PROJECT_ROOT_PATH.indexOf("\\htdocs\\");
14
+ const htdocsIndex = projectRootPath.indexOf("\\htdocs\\");
15
15
  if (htdocsIndex === -1) {
16
16
  console.error(
17
17
  "Invalid PROJECT_ROOT_PATH. The path does not contain \\htdocs\\"
@@ -22,17 +22,16 @@ function bsConfigUrls(projectSettings) {
22
22
  };
23
23
  }
24
24
  // Extract the path up to and including 'htdocs\\'
25
- const basePathToRemove = projectSettings.PROJECT_ROOT_PATH.substring(
25
+ const basePathToRemove = projectRootPath.substring(
26
26
  0,
27
27
  htdocsIndex + "\\htdocs\\".length
28
28
  );
29
29
  // Escape backslashes for the regex pattern
30
30
  const escapedBasePathToRemove = basePathToRemove.replace(/\\/g, "\\\\");
31
31
  // Remove the base path and replace backslashes with forward slashes for URL compatibility
32
- const relativeWebPath = projectSettings.PROJECT_ROOT_PATH.replace(
33
- new RegExp(`^${escapedBasePathToRemove}`),
34
- ""
35
- ).replace(/\\/g, "/");
32
+ const relativeWebPath = projectRootPath
33
+ .replace(new RegExp(`^${escapedBasePathToRemove}`), "")
34
+ .replace(/\\/g, "/");
36
35
  // Construct the Browser Sync command with the correct proxy URL, being careful not to affect the protocol part
37
36
  let proxyUrl = `http://localhost/${relativeWebPath}`;
38
37
  // Ensure the proxy URL does not end with a slash before appending '/public'
@@ -190,11 +189,7 @@ const ws = new WebSocket("ws://localhost:8080");
190
189
  async function createUpdateGitignoreFile(baseDir, additions) {
191
190
  const gitignorePath = path.join(baseDir, ".gitignore");
192
191
  if (checkExcludeFiles(gitignorePath)) return;
193
- // Check if the .gitignore file exists, create if it doesn't
194
192
  let gitignoreContent = "";
195
- if (fs.existsSync(gitignorePath)) {
196
- gitignoreContent = fs.readFileSync(gitignorePath, "utf8");
197
- }
198
193
  additions.forEach((addition) => {
199
194
  if (!gitignoreContent.includes(addition)) {
200
195
  gitignoreContent += `\n${addition}`;
@@ -206,6 +201,7 @@ async function createUpdateGitignoreFile(baseDir, additions) {
206
201
  }
207
202
  // Recursive copy function
208
203
  function copyRecursiveSync(src, dest, answer) {
204
+ var _a;
209
205
  console.log("🚀 ~ copyRecursiveSync ~ dest:", dest);
210
206
  console.log("🚀 ~ copyRecursiveSync ~ src:", src);
211
207
  const exists = fs.existsSync(src);
@@ -213,14 +209,18 @@ function copyRecursiveSync(src, dest, answer) {
213
209
  const isDirectory = exists && stats && stats.isDirectory();
214
210
  if (isDirectory) {
215
211
  const destLower = dest.toLowerCase();
216
- console.log("🚀 ~ copyRecursiveSync ~ destLower:", destLower);
217
- const destIncludeWebsocket = destLower.includes("src\\lib\\websocket");
218
- console.log(
219
- "🚀 ~ copyRecursiveSync ~ destIncludeWebsocket:",
220
- destIncludeWebsocket
221
- );
222
212
  if (!answer.websocket && destLower.includes("src\\lib\\websocket")) return;
223
213
  if (!answer.prisma && destLower.includes("src\\lib\\prisma")) return;
214
+ const destModified = dest.replace(/\\/g, "/");
215
+ if (
216
+ (_a =
217
+ updateAnswer === null || updateAnswer === void 0
218
+ ? void 0
219
+ : updateAnswer.excludeFilePath) === null || _a === void 0
220
+ ? void 0
221
+ : _a.includes(destModified)
222
+ )
223
+ return;
224
224
  if (!fs.existsSync(dest)) fs.mkdirSync(dest, { recursive: true });
225
225
  fs.readdirSync(src).forEach((childItemName) => {
226
226
  copyRecursiveSync(
@@ -314,16 +314,8 @@ function modifyLayoutPHP(baseDir, useTailwind) {
314
314
  async function createOrUpdateEnvFile(baseDir, content) {
315
315
  const envPath = path.join(baseDir, ".env");
316
316
  if (checkExcludeFiles(envPath)) return;
317
- let envContent = fs.existsSync(envPath)
318
- ? fs.readFileSync(envPath, "utf8")
319
- : "";
320
- // Check if the content already exists in the .env file
321
- if (!envContent.includes(content)) {
322
- envContent += `${envContent !== "" ? "\n\n" : ""}${content}`;
323
- fs.writeFileSync(envPath, envContent, { flag: "w" });
324
- } else {
325
- console.log(".env file already contains the content.");
326
- }
317
+ console.log("🚀 ~ content:", content);
318
+ fs.writeFileSync(envPath, content, { flag: "w" });
327
319
  }
328
320
  function checkExcludeFiles(destPath) {
329
321
  var _a, _b;
@@ -356,10 +348,7 @@ async function createDirectoryStructure(baseDir, answer) {
356
348
  ? void 0
357
349
  : updateAnswer.isUpdate
358
350
  ) {
359
- filesToCopy.push(
360
- { src: "/.env", dest: "/.env" },
361
- { src: "/tsconfig.json", dest: "/tsconfig.json" }
362
- );
351
+ filesToCopy.push({ src: "/tsconfig.json", dest: "/tsconfig.json" });
363
352
  if (updateAnswer.tailwindcss) {
364
353
  filesToCopy.push(
365
354
  { src: "/postcss.config.js", dest: "/postcss.config.js" },
@@ -402,13 +391,6 @@ async function createDirectoryStructure(baseDir, answer) {
402
391
  } else {
403
392
  modifyLayoutPHP(baseDir, false);
404
393
  }
405
- const prismaEnvContent = `# Environment variables declared in this file are automatically made available to Prisma.
406
- # See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema
407
-
408
- # Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB.
409
- # See the documentation for all the connection string options: https://pris.ly/d/connection-strings
410
-
411
- DATABASE_URL="postgresql://johndoe:randompassword@localhost:5432/mydb?schema=public"`;
412
394
  const prismaPHPEnvContent = `# Prisma PHP Auth Secret Key For development only - Change this in production
413
395
  AUTH_SECRET=uxsjXVPHN038DEYls2Kw0QUgBcXKUyrjv416nIFWPY4=
414
396
 
@@ -420,10 +402,18 @@ AUTH_SECRET=uxsjXVPHN038DEYls2Kw0QUgBcXKUyrjv416nIFWPY4=
420
402
  # SMTP_ENCRYPTION=ssl or tls
421
403
  # MAIL_FROM=john.doe@gmail.com
422
404
  # MAIL_FROM_NAME="John Doe"`;
423
- let envContent = prismaPHPEnvContent;
424
- await createOrUpdateEnvFile(baseDir, envContent);
425
405
  if (answer.prisma) {
426
- // await createOrUpdateEnvFile(baseDir, prismaEnvContent);
406
+ const prismaEnvContent = `# Environment variables declared in this file are automatically made available to Prisma.
407
+ # See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema
408
+
409
+ # Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB.
410
+ # See the documentation for all the connection string options: https://pris.ly/d/connection-strings
411
+
412
+ DATABASE_URL="postgresql://johndoe:randompassword@localhost:5432/mydb?schema=public"`;
413
+ const envContent = `${prismaEnvContent}\n\n${prismaPHPEnvContent}`;
414
+ await createOrUpdateEnvFile(baseDir, envContent);
415
+ } else {
416
+ await createOrUpdateEnvFile(baseDir, prismaPHPEnvContent);
427
417
  }
428
418
  // Add vendor to .gitignore
429
419
  await createUpdateGitignoreFile(baseDir, ["vendor", ".env", "node_modules"]);
@@ -641,7 +631,10 @@ async function main() {
641
631
  console.log(chalk.red("Installation cancelled."));
642
632
  return;
643
633
  }
644
- execSync(`npm install -g create-prisma-php-app`, { stdio: "inherit" }); // TODO: Uncomment this line before publishing the package
634
+ execSync(`npm uninstall -g create-prisma-php-app`, { stdio: "inherit" });
635
+ execSync(`npm install -g create-prisma-php-app@test-update`, {
636
+ stdio: "inherit",
637
+ }); // TODO: Uncomment this line before publishing the package
645
638
  // Support for browser-sync
646
639
  execSync(`npm install -g browser-sync`, { stdio: "inherit" });
647
640
  // Create the project directory
@@ -729,16 +722,7 @@ async function main() {
729
722
  }
730
723
  const version = await fetchPackageVersion("create-prisma-php-app");
731
724
  const projectPathModified = projectPath.replace(/\\/g, "\\");
732
- const PHP_GENERATE_CLASS_PATH = answer.prisma
733
- ? "src/Lib/Prisma/Classes"
734
- : "";
735
- const projectSettings = {
736
- PROJECT_NAME: answer.projectName,
737
- PROJECT_ROOT_PATH: projectPathModified,
738
- PHP_ROOT_PATH_EXE: "C:\\\\xampp\\\\php\\\\php.exe",
739
- PHP_GENERATE_CLASS_PATH,
740
- };
741
- const bsConfig = bsConfigUrls(projectSettings);
725
+ const bsConfig = bsConfigUrls(projectPathModified);
742
726
  const phpGenerateClassPath = answer.prisma ? "src/Lib/Prisma/Classes" : "";
743
727
  const prismaPhpConfig = {
744
728
  projectName: answer.projectName,
@@ -765,12 +749,25 @@ async function main() {
765
749
  JSON.stringify(prismaPhpConfig, null, 2),
766
750
  { flag: "w" }
767
751
  );
768
- execSync(
769
- `C:\\xampp\\php\\php.exe C:\\ProgramData\\ComposerSetup\\bin\\composer.phar install`,
770
- {
771
- stdio: "inherit",
772
- }
773
- );
752
+ if (
753
+ updateAnswer === null || updateAnswer === void 0
754
+ ? void 0
755
+ : updateAnswer.isUpdate
756
+ ) {
757
+ execSync(
758
+ `C:\\xampp\\php\\php.exe C:\\ProgramData\\ComposerSetup\\bin\\composer.phar update`,
759
+ {
760
+ stdio: "inherit",
761
+ }
762
+ );
763
+ } else {
764
+ execSync(
765
+ `C:\\xampp\\php\\php.exe C:\\ProgramData\\ComposerSetup\\bin\\composer.phar install`,
766
+ {
767
+ stdio: "inherit",
768
+ }
769
+ );
770
+ }
774
771
  console.log(
775
772
  `${chalk.green("Success!")} Prisma PHP project successfully created in ${
776
773
  answer.projectName
@@ -17,6 +17,8 @@ model User {
17
17
  password String?
18
18
  emailVerified DateTime?
19
19
  image String?
20
+ createdAt DateTime @default(now())
21
+ updatedAt DateTime @updatedAt
20
22
 
21
23
  roleId Int?
22
24
  userRole UserRole? @relation(fields: [roleId], references: [id])