create-prisma-php-app 4.0.0-alpha.19 → 4.0.0-alpha.20
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/dist/.htaccess +54 -41
- package/dist/bootstrap.php +133 -88
- package/dist/index.js +167 -72
- package/dist/settings/auto-swagger-docs.ts +196 -95
- package/dist/settings/bs-config.ts +56 -58
- package/dist/settings/restart-mcp.ts +58 -0
- package/dist/settings/restart-websocket.ts +44 -45
- package/dist/settings/utils.ts +240 -0
- package/dist/src/Lib/Headers/Boom.php +152 -168
- package/dist/src/Lib/IncludeTracker.php +1 -1
- package/dist/src/Lib/MCP/WeatherTools.php +104 -0
- package/dist/src/Lib/MCP/mcp-server.php +80 -0
- package/dist/src/Lib/MainLayout.php +19 -4
- package/dist/src/Lib/Middleware/CorsMiddleware.php +158 -0
- package/dist/src/Lib/PHPX/Fragment.php +32 -0
- package/dist/src/Lib/PHPX/PHPX.php +119 -5
- package/dist/src/Lib/PHPX/TemplateCompiler.php +78 -21
- package/dist/src/Lib/PHPX/TwMerge.php +305 -154
- package/dist/src/Lib/PHPX/TypeCoercer.php +5 -5
- package/dist/src/Lib/Request.php +4 -1
- package/dist/src/Lib/Security/RateLimiter.php +33 -0
- package/dist/src/Lib/Validator.php +20 -6
- package/dist/src/Lib/Websocket/websocket-server.php +105 -14
- package/dist/src/app/index.php +24 -5
- package/dist/src/app/js/index.js +1 -1
- package/package.json +1 -1
- package/dist/settings/restart-websocket.bat +0 -28
- package/dist/src/app/assets/images/prisma-php-black.svg +0 -6
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{execSync,spawnSync}from"child_process";import fs from"fs";import{fileURLToPath}from"url";import path from"path";import chalk from"chalk";import prompts from"prompts";import https from"https";import{randomBytes}from"crypto";const __filename=fileURLToPath(import.meta.url),__dirname=path.dirname(__filename);let updateAnswer=null;const nonBackendFiles=["favicon.ico","\\src\\app\\index.php","metadata.php","not-found.php","error.php"],dockerFiles=[".dockerignore","docker-compose.yml","Dockerfile","apache.conf"];function bsConfigUrls(e){const s=e.indexOf("\\htdocs\\");if(-1===s)return{bsTarget:"",bsPathRewrite:{}};const t=e.substring(0,s+"\\htdocs\\".length).replace(/\\/g,"\\\\"),n=e.replace(new RegExp(`^${t}`),"").replace(/\\/g,"/");let c=`http://localhost/${n}`;c=c.endsWith("/")?c.slice(0,-1):c;const o=c.replace(/(?<!:)(\/\/+)/g,"/"),i=n.replace(/\/\/+/g,"/");return{bsTarget:`${o}/`,bsPathRewrite:{"^/":`/${i.startsWith("/")?i.substring(1):i}/`}}}async function updatePackageJson(e,s){const t=path.join(e,"package.json");if(checkExcludeFiles(t))return;const n=JSON.parse(fs.readFileSync(t,"utf8"));n.scripts={...n.scripts,projectName:"tsx settings/project-name.ts"};let c=[];if(s.tailwindcss&&(n.scripts={...n.scripts,tailwind:"postcss src/app/css/tailwind.css -o src/app/css/styles.css --watch","tailwind:build":"postcss src/app/css/tailwind.css -o src/app/css/styles.css"},c.push("tailwind")),s.websocket&&(n.scripts={...n.scripts,websocket:"tsx settings/restart-websocket.ts"},c.push("websocket")),s.docker&&(n.scripts={...n.scripts,docker:"docker-compose up"},c.push("docker")),s.swaggerDocs){const e=s.prisma?"tsx settings/auto-swagger-docs.ts":"tsx settings/swagger-config.ts";n.scripts={...n.scripts,"create-swagger-docs":e}}let o={...n.scripts};o.browserSync="tsx settings/bs-config.ts",o["browserSync:build"]="tsx settings/build.ts",o.dev=`npm-run-all projectName -p browserSync ${c.join(" ")}`,o.build=`npm-run-all${s.tailwindcss?" tailwind:build":""} browserSync:build`,n.scripts=o,n.type="module",fs.writeFileSync(t,JSON.stringify(n,null,2))}async function updateComposerJson(e){checkExcludeFiles(path.join(e,"composer.json"))}async function updateIndexJsForWebSocket(e,s){if(!s.websocket)return;const t=path.join(e,"src","app","js","index.js");if(checkExcludeFiles(t))return;let n=fs.readFileSync(t,"utf8");n+='\n// WebSocket initialization\nvar ws = new WebSocket("ws://localhost:8080");\n',fs.writeFileSync(t,n,"utf8")}function generateAuthSecret(){return randomBytes(33).toString("base64")}function generateHexEncodedKey(e=16){return randomBytes(e).toString("hex")}function copyRecursiveSync(e,s,t){const n=fs.existsSync(e),c=n&&fs.statSync(e);if(n&&c&&c.isDirectory()){const n=s.toLowerCase();if(!t.websocket&&n.includes("src\\lib\\websocket"))return;if(t.backendOnly&&n.includes("src\\app\\js")||t.backendOnly&&n.includes("src\\app\\css")||t.backendOnly&&n.includes("src\\app\\assets"))return;if(!t.swaggerDocs&&n.includes("src\\app\\swagger-docs"))return;const c=s.replace(/\\/g,"/");if(updateAnswer?.excludeFilePath?.includes(c))return;fs.existsSync(s)||fs.mkdirSync(s,{recursive:!0}),fs.readdirSync(e).forEach((n=>{copyRecursiveSync(path.join(e,n),path.join(s,n),t)}))}else{if(checkExcludeFiles(s))return;if(!t.tailwindcss&&(s.includes("tailwind.css")||s.includes("styles.css")))return;if(!t.websocket&&(s.includes("restart-websocket.ts")||s.includes("restart-websocket.bat")))return;if(!t.docker&&dockerFiles.some((e=>s.includes(e))))return;if(t.backendOnly&&nonBackendFiles.some((e=>s.includes(e))))return;if(!t.backendOnly&&s.includes("route.php"))return;if(t.backendOnly&&!t.swaggerDocs&&s.includes("layout.php"))return;if(!t.swaggerDocs&&s.includes("swagger-config.ts"))return;if(t.tailwindcss&&s.includes("index.css"))return;if((!t.swaggerDocs||!t.prisma)&&(s.includes("auto-swagger-docs.ts")||s.includes("prisma-schema-config.json")))return;fs.copyFileSync(e,s,0)}}async function executeCopy(e,s,t){s.forEach((({src:s,dest:n})=>{copyRecursiveSync(path.join(__dirname,s),path.join(e,n),t)}))}function modifyPostcssConfig(e){const s=path.join(e,"postcss.config.js");if(checkExcludeFiles(s))return;fs.writeFileSync(s,'export default {\n plugins: {\n "@tailwindcss/postcss": {},\n cssnano: {},\n },\n};',{flag:"w"})}function modifyLayoutPHP(e,s){const t=path.join(e,"src","app","layout.php");if(!checkExcludeFiles(t))try{let e=fs.readFileSync(t,"utf8"),n="";s.backendOnly||(s.tailwindcss||(n='\n <link href="<?= Request::baseUrl; ?>/css/index.css" rel="stylesheet" />'),n+='\n <script src="<?= Request::baseUrl; ?>/js/morphdom-umd.min.js"><\/script>\n <script src="<?= Request::baseUrl; ?>/js/json5.min.js"><\/script>\n <script src="<?= Request::baseUrl; ?>/js/index.js"><\/script>');let c="";s.backendOnly||(c=s.tailwindcss?` <link href="<?= Request::baseUrl; ?>/css/styles.css" rel="stylesheet" /> ${n}`:n),e=e.replace("</head>",`${c}\n</head>`),fs.writeFileSync(t,e,{flag:"w"})}catch(e){}}async function createOrUpdateEnvFile(e,s){const t=path.join(e,".env");checkExcludeFiles(t)||fs.writeFileSync(t,s,{flag:"w"})}function checkExcludeFiles(e){return!!updateAnswer?.isUpdate&&(updateAnswer?.excludeFilePath?.includes(e.replace(/\\/g,"/"))??!1)}async function createDirectoryStructure(e,s){const t=[{src:"/bootstrap.php",dest:"/bootstrap.php"},{src:"/.htaccess",dest:"/.htaccess"},{src:"/tsconfig.json",dest:"/tsconfig.json"},{src:"/app-gitignore",dest:"/.gitignore"}];s.tailwindcss&&t.push({src:"/postcss.config.js",dest:"/postcss.config.js"});const n=[{src:"/settings",dest:"/settings"},{src:"/src",dest:"/src"}];s.docker&&n.push({src:"/.dockerignore",dest:"/.dockerignore"},{src:"/docker-compose.yml",dest:"/docker-compose.yml"},{src:"/Dockerfile",dest:"/Dockerfile"},{src:"/apache.conf",dest:"/apache.conf"}),t.forEach((({src:s,dest:t})=>{const n=path.join(__dirname,s),c=path.join(e,t);if(checkExcludeFiles(c))return;const o=fs.readFileSync(n,"utf8");fs.writeFileSync(c,o,{flag:"w"})})),await executeCopy(e,n,s),await updatePackageJson(e,s),await updateComposerJson(e),s.backendOnly||await updateIndexJsForWebSocket(e,s),s.tailwindcss&&modifyPostcssConfig(e),(s.tailwindcss||!s.backendOnly||s.swaggerDocs)&&modifyLayoutPHP(e,s);const c=generateAuthSecret(),o=generateHexEncodedKey(),i=`# Authentication secret key for JWT or session encryption.\nAUTH_SECRET="${c}"\n# Name of the authentication cookie.\nAUTH_COOKIE_NAME="${generateHexEncodedKey(8)}"\n\n# PHPMailer SMTP configuration (uncomment and set as needed)\n# SMTP_HOST="smtp.gmail.com" # Your SMTP host\n# SMTP_USERNAME="john.doe@gmail.com" # Your SMTP username\n# SMTP_PASSWORD="123456" # Your SMTP password\n# SMTP_PORT="587" # 587 for TLS, 465 for SSL, or your SMTP port\n# SMTP_ENCRYPTION="ssl" # ssl or tls\n# MAIL_FROM="john.doe@gmail.com" # Sender email address\n# MAIL_FROM_NAME="John Doe" # Sender name\n\n# Show errors in the browser (development only). Set to false in production.\nSHOW_ERRORS="true"\n\n# Application timezone (default: UTC)\nAPP_TIMEZONE="UTC"\n\n# Application environment (development or production)\nAPP_ENV="development"\n\n# Enable or disable application cache (default: false)\nCACHE_ENABLED="false"\n# Cache time-to-live in seconds (default: 600)\nCACHE_TTL="600"\n\n# Local storage key for browser storage (auto-generated if not set).\n# Spaces will be replaced with underscores and converted to lowercase.\nLOCALSTORE_KEY="${o}"\n\n# Secret key for encrypting function calls.\nFUNCTION_CALL_SECRET="${generateHexEncodedKey(32)}"`;if(s.prisma){const s=`${'# Environment variables declared in this file are automatically made available to Prisma.\n# See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema\n\n# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB.\n# See the documentation for all the connection string options: https://pris.ly/d/connection-strings\n\nDATABASE_URL="postgresql://johndoe:randompassword@localhost:5432/mydb?schema=public"'}\n\n${i}`;await createOrUpdateEnvFile(e,s)}else await createOrUpdateEnvFile(e,i)}async function getAnswer(e={}){const s=[];e.projectName||s.push({type:"text",name:"projectName",message:"What is your project named?",initial:"my-app"}),e.backendOnly||updateAnswer?.isUpdate||s.push({type:"toggle",name:"backendOnly",message:`Would you like to create a ${chalk.blue("backend-only project")}?`,initial:!1,active:"Yes",inactive:"No"});const t=()=>{process.exit(0)},n=await prompts(s,{onCancel:t}),c=[];n.backendOnly??e.backendOnly??!1?(e.swaggerDocs||c.push({type:"toggle",name:"swaggerDocs",message:`Would you like to use ${chalk.blue("Swagger Docs")}?`,initial:!1,active:"Yes",inactive:"No"}),e.websocket||c.push({type:"toggle",name:"websocket",message:`Would you like to use ${chalk.blue("Websocket")}?`,initial:!0,active:"Yes",inactive:"No"}),e.prisma||c.push({type:"toggle",name:"prisma",message:`Would you like to use ${chalk.blue("Prisma PHP ORM")}?`,initial:!0,active:"Yes",inactive:"No"}),e.docker||c.push({type:"toggle",name:"docker",message:`Would you like to use ${chalk.blue("Docker")}?`,initial:!1,active:"Yes",inactive:"No"})):(e.swaggerDocs||c.push({type:"toggle",name:"swaggerDocs",message:`Would you like to use ${chalk.blue("Swagger Docs")}?`,initial:!1,active:"Yes",inactive:"No"}),e.tailwindcss||c.push({type:"toggle",name:"tailwindcss",message:`Would you like to use ${chalk.blue("Tailwind CSS")}?`,initial:!1,active:"Yes",inactive:"No"}),e.websocket||c.push({type:"toggle",name:"websocket",message:`Would you like to use ${chalk.blue("Websocket")}?`,initial:!1,active:"Yes",inactive:"No"}),e.prisma||c.push({type:"toggle",name:"prisma",message:`Would you like to use ${chalk.blue("Prisma PHP ORM")}?`,initial:!1,active:"Yes",inactive:"No"}),e.docker||c.push({type:"toggle",name:"docker",message:`Would you like to use ${chalk.blue("Docker")}?`,initial:!1,active:"Yes",inactive:"No"}));const o=await prompts(c,{onCancel:t});return{projectName:n.projectName?String(n.projectName).trim().replace(/ /g,"-"):e.projectName??"my-app",backendOnly:n.backendOnly??e.backendOnly??!1,swaggerDocs:o.swaggerDocs??e.swaggerDocs??!1,tailwindcss:o.tailwindcss??e.tailwindcss??!1,websocket:o.websocket??e.websocket??!1,prisma:o.prisma??e.prisma??!1,docker:o.docker??e.docker??!1}}async function uninstallNpmDependencies(e,s,t=!1){s.forEach((e=>{}));const n=`npm uninstall ${t?"--save-dev":"--save"} ${s.join(" ")}`;execSync(n,{stdio:"inherit",cwd:e})}async function uninstallComposerDependencies(e,s){s.forEach((e=>{}));const t=`C:\\xampp\\php\\php.exe C:\\ProgramData\\ComposerSetup\\bin\\composer.phar remove ${s.join(" ")}`;execSync(t,{stdio:"inherit",cwd:e})}function fetchPackageVersion(e){return new Promise(((s,t)=>{https.get(`https://registry.npmjs.org/${e}`,(e=>{let n="";e.on("data",(e=>n+=e)),e.on("end",(()=>{try{const e=JSON.parse(n);s(e["dist-tags"].latest)}catch(e){t(new Error("Failed to parse JSON response"))}}))})).on("error",(e=>t(e)))}))}const readJsonFile=e=>{const s=fs.readFileSync(e,"utf8");return JSON.parse(s)};function compareVersions(e,s){const t=e.split(".").map(Number),n=s.split(".").map(Number);for(let e=0;e<t.length;e++){if(t[e]>n[e])return 1;if(t[e]<n[e])return-1}return 0}function getInstalledPackageVersion(e){try{const s=execSync(`npm list -g ${e} --depth=0`).toString().match(new RegExp(`${e}@(\\d+\\.\\d+\\.\\d+)`));return s?s[1]:null}catch(e){return null}}
|
|
2
|
+
import{execSync,spawnSync}from"child_process";import fs from"fs";import{fileURLToPath}from"url";import path from"path";import chalk from"chalk";import prompts from"prompts";import https from"https";import{randomBytes}from"crypto";const __filename=fileURLToPath(import.meta.url),__dirname=path.dirname(__filename);let updateAnswer=null;const nonBackendFiles=["favicon.ico","\\src\\app\\index.php","metadata.php","not-found.php","error.php"],dockerFiles=[".dockerignore","docker-compose.yml","Dockerfile","apache.conf"];function bsConfigUrls(e){const s=e.indexOf("\\htdocs\\");if(-1===s)return{bsTarget:"",bsPathRewrite:{}};const t=e.substring(0,s+"\\htdocs\\".length).replace(/\\/g,"\\\\"),n=e.replace(new RegExp(`^${t}`),"").replace(/\\/g,"/");let c=`http://localhost/${n}`;c=c.endsWith("/")?c.slice(0,-1):c;const o=c.replace(/(?<!:)(\/\/+)/g,"/"),i=n.replace(/\/\/+/g,"/");return{bsTarget:`${o}/`,bsPathRewrite:{"^/":`/${i.startsWith("/")?i.substring(1):i}/`}}}async function updatePackageJson(e,s){const t=path.join(e,"package.json");if(checkExcludeFiles(t))return;const n=JSON.parse(fs.readFileSync(t,"utf8"));n.scripts={...n.scripts,projectName:"tsx settings/project-name.ts"};let c=[];if(s.tailwindcss&&(n.scripts={...n.scripts,tailwind:"postcss src/app/css/tailwind.css -o src/app/css/styles.css --watch","tailwind:build":"postcss src/app/css/tailwind.css -o src/app/css/styles.css"},c.push("tailwind")),s.websocket&&(n.scripts={...n.scripts,websocket:"tsx settings/restart-websocket.ts"},c.push("websocket")),s.docker&&(n.scripts={...n.scripts,docker:"docker-compose up"},c.push("docker")),s.swaggerDocs){const e=s.prisma?"tsx settings/auto-swagger-docs.ts":"tsx settings/swagger-config.ts";n.scripts={...n.scripts,"create-swagger-docs":e}}let o={...n.scripts};o.browserSync="tsx settings/bs-config.ts",o["browserSync:build"]="tsx settings/build.ts",o.dev=`npm-run-all projectName -p browserSync ${c.join(" ")}`,o.build=`npm-run-all${s.tailwindcss?" tailwind:build":""} browserSync:build`,n.scripts=o,n.type="module",fs.writeFileSync(t,JSON.stringify(n,null,2))}async function updateComposerJson(e){checkExcludeFiles(path.join(e,"composer.json"))}async function updateIndexJsForWebSocket(e,s){if(!s.websocket)return;const t=path.join(e,"src","app","js","index.js");if(checkExcludeFiles(t))return;let n=fs.readFileSync(t,"utf8");n+='\n// WebSocket initialization\nvar ws = new WebSocket("ws://localhost:8080");\n',fs.writeFileSync(t,n,"utf8")}function generateAuthSecret(){return randomBytes(33).toString("base64")}function generateHexEncodedKey(e=16){return randomBytes(e).toString("hex")}function copyRecursiveSync(e,s,t){const n=fs.existsSync(e),c=n&&fs.statSync(e);if(n&&c&&c.isDirectory()){const n=s.toLowerCase();if(!t.websocket&&n.includes("src\\lib\\websocket"))return;if(t.backendOnly&&n.includes("src\\app\\js")||t.backendOnly&&n.includes("src\\app\\css")||t.backendOnly&&n.includes("src\\app\\assets"))return;if(!t.swaggerDocs&&n.includes("src\\app\\swagger-docs"))return;const c=s.replace(/\\/g,"/");if(updateAnswer?.excludeFilePath?.includes(c))return;fs.existsSync(s)||fs.mkdirSync(s,{recursive:!0}),fs.readdirSync(e).forEach((n=>{copyRecursiveSync(path.join(e,n),path.join(s,n),t)}))}else{if(checkExcludeFiles(s))return;if(!t.tailwindcss&&(s.includes("tailwind.css")||s.includes("styles.css")))return;if(!t.websocket&&s.includes("restart-websocket.ts"))return;if(!t.docker&&dockerFiles.some((e=>s.includes(e))))return;if(t.backendOnly&&nonBackendFiles.some((e=>s.includes(e))))return;if(!t.backendOnly&&s.includes("route.php"))return;if(t.backendOnly&&!t.swaggerDocs&&s.includes("layout.php"))return;if(!t.swaggerDocs&&s.includes("swagger-config.ts"))return;if(t.tailwindcss&&s.includes("index.css"))return;if((!t.swaggerDocs||!t.prisma)&&(s.includes("auto-swagger-docs.ts")||s.includes("prisma-schema-config.json")))return;fs.copyFileSync(e,s,0)}}async function executeCopy(e,s,t){s.forEach((({src:s,dest:n})=>{copyRecursiveSync(path.join(__dirname,s),path.join(e,n),t)}))}function modifyPostcssConfig(e){const s=path.join(e,"postcss.config.js");if(checkExcludeFiles(s))return;fs.writeFileSync(s,'export default {\n plugins: {\n "@tailwindcss/postcss": {},\n cssnano: {},\n },\n};',{flag:"w"})}function modifyLayoutPHP(e,s){const t=path.join(e,"src","app","layout.php");if(!checkExcludeFiles(t))try{let e=fs.readFileSync(t,"utf8"),n="";s.backendOnly||(s.tailwindcss||(n='\n <link href="<?= Request::baseUrl; ?>/css/index.css" rel="stylesheet" />'),n+='\n <script src="<?= Request::baseUrl; ?>/js/morphdom-umd.min.js"><\/script>\n <script src="<?= Request::baseUrl; ?>/js/json5.min.js"><\/script>\n <script src="<?= Request::baseUrl; ?>/js/index.js"><\/script>');let c="";s.backendOnly||(c=s.tailwindcss?` <link href="<?= Request::baseUrl; ?>/css/styles.css" rel="stylesheet" /> ${n}`:n),e=e.replace("</head>",`${c}\n</head>`),fs.writeFileSync(t,e,{flag:"w"})}catch(e){}}async function createOrUpdateEnvFile(e,s){const t=path.join(e,".env");checkExcludeFiles(t)||fs.writeFileSync(t,s,{flag:"w"})}function checkExcludeFiles(e){return!!updateAnswer?.isUpdate&&(updateAnswer?.excludeFilePath?.includes(e.replace(/\\/g,"/"))??!1)}async function createDirectoryStructure(e,s){const t=[{src:"/bootstrap.php",dest:"/bootstrap.php"},{src:"/.htaccess",dest:"/.htaccess"},{src:"/tsconfig.json",dest:"/tsconfig.json"},{src:"/app-gitignore",dest:"/.gitignore"}];s.tailwindcss&&t.push({src:"/postcss.config.js",dest:"/postcss.config.js"});const n=[{src:"/settings",dest:"/settings"},{src:"/src",dest:"/src"}];s.docker&&n.push({src:"/.dockerignore",dest:"/.dockerignore"},{src:"/docker-compose.yml",dest:"/docker-compose.yml"},{src:"/Dockerfile",dest:"/Dockerfile"},{src:"/apache.conf",dest:"/apache.conf"}),t.forEach((({src:s,dest:t})=>{const n=path.join(__dirname,s),c=path.join(e,t);if(checkExcludeFiles(c))return;const o=fs.readFileSync(n,"utf8");fs.writeFileSync(c,o,{flag:"w"})})),await executeCopy(e,n,s),await updatePackageJson(e,s),await updateComposerJson(e),s.backendOnly||await updateIndexJsForWebSocket(e,s),s.tailwindcss&&modifyPostcssConfig(e),(s.tailwindcss||!s.backendOnly||s.swaggerDocs)&&modifyLayoutPHP(e,s);const c=generateAuthSecret(),o=generateHexEncodedKey(),i=`# Authentication secret key for JWT or session encryption.\nAUTH_SECRET="${c}"\n# Name of the authentication cookie.\nAUTH_COOKIE_NAME="${generateHexEncodedKey(8)}"\n\n# PHPMailer SMTP configuration (uncomment and set as needed)\n# SMTP_HOST="smtp.gmail.com" # Your SMTP host\n# SMTP_USERNAME="john.doe@gmail.com" # Your SMTP username\n# SMTP_PASSWORD="123456" # Your SMTP password\n# SMTP_PORT="587" # 587 for TLS, 465 for SSL, or your SMTP port\n# SMTP_ENCRYPTION="ssl" # ssl or tls\n# MAIL_FROM="john.doe@gmail.com" # Sender email address\n# MAIL_FROM_NAME="John Doe" # Sender name\n\n# Show errors in the browser (development only). Set to false in production.\nSHOW_ERRORS="true"\n\n# Application timezone (default: UTC)\nAPP_TIMEZONE="UTC"\n\n# Application environment (development or production)\nAPP_ENV="development"\n\n# Enable or disable application cache (default: false)\nCACHE_ENABLED="false"\n# Cache time-to-live in seconds (default: 600)\nCACHE_TTL="600"\n\n# Local storage key for browser storage (auto-generated if not set).\n# Spaces will be replaced with underscores and converted to lowercase.\nLOCALSTORE_KEY="${o}"\n\n# Secret key for encrypting function calls.\nFUNCTION_CALL_SECRET="${generateHexEncodedKey(32)}"`;if(s.prisma){const s=`${'# Environment variables declared in this file are automatically made available to Prisma.\n# See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema\n\n# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB.\n# See the documentation for all the connection string options: https://pris.ly/d/connection-strings\n\nDATABASE_URL="postgresql://johndoe:randompassword@localhost:5432/mydb?schema=public"'}\n\n${i}`;await createOrUpdateEnvFile(e,s)}else await createOrUpdateEnvFile(e,i)}async function getAnswer(e={}){const s=[];e.projectName||s.push({type:"text",name:"projectName",message:"What is your project named?",initial:"my-app"}),e.backendOnly||updateAnswer?.isUpdate||s.push({type:"toggle",name:"backendOnly",message:`Would you like to create a ${chalk.blue("backend-only project")}?`,initial:!1,active:"Yes",inactive:"No"});const t=()=>{process.exit(0)},n=await prompts(s,{onCancel:t}),c=[];n.backendOnly??e.backendOnly??!1?(e.swaggerDocs||c.push({type:"toggle",name:"swaggerDocs",message:`Would you like to use ${chalk.blue("Swagger Docs")}?`,initial:!1,active:"Yes",inactive:"No"}),e.websocket||c.push({type:"toggle",name:"websocket",message:`Would you like to use ${chalk.blue("Websocket")}?`,initial:!1,active:"Yes",inactive:"No"}),e.prisma||c.push({type:"toggle",name:"prisma",message:`Would you like to use ${chalk.blue("Prisma PHP ORM")}?`,initial:!1,active:"Yes",inactive:"No"}),e.docker||c.push({type:"toggle",name:"docker",message:`Would you like to use ${chalk.blue("Docker")}?`,initial:!1,active:"Yes",inactive:"No"})):(e.swaggerDocs||c.push({type:"toggle",name:"swaggerDocs",message:`Would you like to use ${chalk.blue("Swagger Docs")}?`,initial:!1,active:"Yes",inactive:"No"}),e.tailwindcss||c.push({type:"toggle",name:"tailwindcss",message:`Would you like to use ${chalk.blue("Tailwind CSS")}?`,initial:!1,active:"Yes",inactive:"No"}),e.websocket||c.push({type:"toggle",name:"websocket",message:`Would you like to use ${chalk.blue("Websocket")}?`,initial:!1,active:"Yes",inactive:"No"}),e.prisma||c.push({type:"toggle",name:"prisma",message:`Would you like to use ${chalk.blue("Prisma PHP ORM")}?`,initial:!1,active:"Yes",inactive:"No"}),e.docker||c.push({type:"toggle",name:"docker",message:`Would you like to use ${chalk.blue("Docker")}?`,initial:!1,active:"Yes",inactive:"No"}));const o=await prompts(c,{onCancel:t});return{projectName:n.projectName?String(n.projectName).trim().replace(/ /g,"-"):e.projectName??"my-app",backendOnly:n.backendOnly??e.backendOnly??!1,swaggerDocs:o.swaggerDocs??e.swaggerDocs??!1,tailwindcss:o.tailwindcss??e.tailwindcss??!1,websocket:o.websocket??e.websocket??!1,prisma:o.prisma??e.prisma??!1,docker:o.docker??e.docker??!1}}async function uninstallNpmDependencies(e,s,t=!1){s.forEach((e=>{}));const n=`npm uninstall ${t?"--save-dev":"--save"} ${s.join(" ")}`;execSync(n,{stdio:"inherit",cwd:e})}async function uninstallComposerDependencies(e,s){s.forEach((e=>{}));const t=`C:\\xampp\\php\\php.exe C:\\ProgramData\\ComposerSetup\\bin\\composer.phar remove ${s.join(" ")}`;execSync(t,{stdio:"inherit",cwd:e})}function fetchPackageVersion(e){return new Promise(((s,t)=>{https.get(`https://registry.npmjs.org/${e}`,(e=>{let n="";e.on("data",(e=>n+=e)),e.on("end",(()=>{try{const e=JSON.parse(n);s(e["dist-tags"].latest)}catch(e){t(new Error("Failed to parse JSON response"))}}))})).on("error",(e=>t(e)))}))}const readJsonFile=e=>{const s=fs.readFileSync(e,"utf8");return JSON.parse(s)};function compareVersions(e,s){const t=e.split(".").map(Number),n=s.split(".").map(Number);for(let e=0;e<t.length;e++){if(t[e]>n[e])return 1;if(t[e]<n[e])return-1}return 0}function getInstalledPackageVersion(e){try{const s=execSync(`npm list -g ${e} --depth=0`).toString().match(new RegExp(`${e}@(\\d+\\.\\d+\\.\\d+)`));return s?s[1]:null}catch(e){return null}}
|
|
3
3
|
/**
|
|
4
4
|
* Install dependencies in the specified directory.
|
|
5
5
|
* @param {string} baseDir - The base directory where to install the dependencies.
|
|
@@ -7,7 +7,11 @@ import{execSync,spawnSync}from"child_process";import fs from"fs";import{fileURLT
|
|
|
7
7
|
* @param {boolean} [isDev=false] - Whether to install the dependencies as devDependencies.
|
|
8
8
|
*/
|
|
9
9
|
async function installNpmDependencies(baseDir, dependencies, isDev = false) {
|
|
10
|
-
|
|
10
|
+
if (!fs.existsSync(path.join(baseDir, "package.json"))) {
|
|
11
|
+
console.log("Initializing new Node.js project...");
|
|
12
|
+
} else {
|
|
13
|
+
console.log("Updating existing Node.js project...");
|
|
14
|
+
}
|
|
11
15
|
// Initialize a package.json if it doesn't exist
|
|
12
16
|
if (!fs.existsSync(path.join(baseDir, "package.json"))) {
|
|
13
17
|
execSync("npm init -y", {
|
|
@@ -132,12 +136,12 @@ export async function installComposerDependencies(baseDir, dependencies) {
|
|
|
132
136
|
const npmPinnedVersions = {
|
|
133
137
|
"@tailwindcss/postcss": "^4.1.11",
|
|
134
138
|
"@types/browser-sync": "^2.29.0",
|
|
135
|
-
"@types/node": "^24.
|
|
139
|
+
"@types/node": "^24.2.1",
|
|
136
140
|
"@types/prompts": "^2.4.9",
|
|
137
141
|
"browser-sync": "^3.0.4",
|
|
138
|
-
chalk: "^5.
|
|
142
|
+
chalk: "^5.5.0",
|
|
139
143
|
"chokidar-cli": "^3.0.0",
|
|
140
|
-
cssnano: "^7.0
|
|
144
|
+
cssnano: "^7.1.0",
|
|
141
145
|
"http-proxy-middleware": "^3.0.5",
|
|
142
146
|
"npm-run-all": "^4.1.5",
|
|
143
147
|
"php-parser": "^3.2.5",
|
|
@@ -146,7 +150,7 @@ const npmPinnedVersions = {
|
|
|
146
150
|
prompts: "^2.4.2",
|
|
147
151
|
tailwindcss: "^4.1.11",
|
|
148
152
|
tsx: "^4.20.3",
|
|
149
|
-
typescript: "^5.
|
|
153
|
+
typescript: "^5.9.2",
|
|
150
154
|
};
|
|
151
155
|
function npmPkg(name) {
|
|
152
156
|
return npmPinnedVersions[name] ? `${name}@${npmPinnedVersions[name]}` : name;
|
|
@@ -173,29 +177,11 @@ async function main() {
|
|
|
173
177
|
let projectName = args[0];
|
|
174
178
|
let answer = null;
|
|
175
179
|
if (projectName) {
|
|
176
|
-
|
|
177
|
-
let useSwaggerDocs = args.includes("--swagger-docs");
|
|
178
|
-
let useTailwind = args.includes("--tailwindcss");
|
|
179
|
-
let useWebsocket = args.includes("--websocket");
|
|
180
|
-
let usePrisma = args.includes("--prisma");
|
|
181
|
-
let useDocker = args.includes("--docker");
|
|
182
|
-
const predefinedAnswers = {
|
|
183
|
-
projectName,
|
|
184
|
-
backendOnly: useBackendOnly,
|
|
185
|
-
swaggerDocs: useSwaggerDocs,
|
|
186
|
-
tailwindcss: useTailwind,
|
|
187
|
-
websocket: useWebsocket,
|
|
188
|
-
prisma: usePrisma,
|
|
189
|
-
docker: useDocker,
|
|
190
|
-
};
|
|
191
|
-
answer = await getAnswer(predefinedAnswers);
|
|
192
|
-
if (answer === null) {
|
|
193
|
-
console.log(chalk.red("Installation cancelled."));
|
|
194
|
-
return;
|
|
195
|
-
}
|
|
180
|
+
// Check if it's an update FIRST
|
|
196
181
|
const currentDir = process.cwd();
|
|
197
182
|
const configPath = path.join(currentDir, "prisma-php.json");
|
|
198
183
|
if (fs.existsSync(configPath)) {
|
|
184
|
+
// It's an update - read existing settings
|
|
199
185
|
const localSettings = readJsonFile(configPath);
|
|
200
186
|
let excludeFiles = [];
|
|
201
187
|
localSettings.excludeFiles?.map((file) => {
|
|
@@ -203,21 +189,75 @@ async function main() {
|
|
|
203
189
|
if (fs.existsSync(filePath))
|
|
204
190
|
excludeFiles.push(filePath.replace(/\\/g, "/"));
|
|
205
191
|
});
|
|
192
|
+
// Set updateAnswer with OLD settings initially (for checkExcludeFiles function)
|
|
206
193
|
updateAnswer = {
|
|
207
194
|
projectName,
|
|
208
|
-
backendOnly:
|
|
209
|
-
swaggerDocs:
|
|
210
|
-
tailwindcss:
|
|
211
|
-
websocket:
|
|
212
|
-
prisma:
|
|
213
|
-
docker:
|
|
195
|
+
backendOnly: localSettings.backendOnly,
|
|
196
|
+
swaggerDocs: localSettings.swaggerDocs,
|
|
197
|
+
tailwindcss: localSettings.tailwindcss,
|
|
198
|
+
websocket: localSettings.websocket,
|
|
199
|
+
prisma: localSettings.prisma,
|
|
200
|
+
docker: localSettings.docker,
|
|
214
201
|
isUpdate: true,
|
|
215
202
|
excludeFiles: localSettings.excludeFiles ?? [],
|
|
216
203
|
excludeFilePath: excludeFiles ?? [],
|
|
217
204
|
filePath: currentDir,
|
|
218
205
|
};
|
|
206
|
+
// For updates, use existing settings but allow CLI overrides
|
|
207
|
+
const predefinedAnswers = {
|
|
208
|
+
projectName,
|
|
209
|
+
backendOnly:
|
|
210
|
+
args.includes("--backend-only") || localSettings.backendOnly,
|
|
211
|
+
swaggerDocs:
|
|
212
|
+
args.includes("--swagger-docs") || localSettings.swaggerDocs,
|
|
213
|
+
tailwindcss:
|
|
214
|
+
args.includes("--tailwindcss") || localSettings.tailwindcss,
|
|
215
|
+
websocket: args.includes("--websocket") || localSettings.websocket,
|
|
216
|
+
prisma: args.includes("--prisma") || localSettings.prisma,
|
|
217
|
+
docker: args.includes("--docker") || localSettings.docker,
|
|
218
|
+
};
|
|
219
|
+
answer = await getAnswer(predefinedAnswers);
|
|
220
|
+
// IMPORTANT: Update updateAnswer with the NEW answer after getting user input
|
|
221
|
+
if (answer !== null) {
|
|
222
|
+
updateAnswer = {
|
|
223
|
+
projectName,
|
|
224
|
+
backendOnly: answer.backendOnly,
|
|
225
|
+
swaggerDocs: answer.swaggerDocs,
|
|
226
|
+
tailwindcss: answer.tailwindcss,
|
|
227
|
+
websocket: answer.websocket,
|
|
228
|
+
prisma: answer.prisma,
|
|
229
|
+
docker: answer.docker,
|
|
230
|
+
isUpdate: true,
|
|
231
|
+
excludeFiles: localSettings.excludeFiles ?? [],
|
|
232
|
+
excludeFilePath: excludeFiles ?? [],
|
|
233
|
+
filePath: currentDir,
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
} else {
|
|
237
|
+
// It's a new project - use CLI arguments
|
|
238
|
+
let useBackendOnly = args.includes("--backend-only");
|
|
239
|
+
let useSwaggerDocs = args.includes("--swagger-docs");
|
|
240
|
+
let useTailwind = args.includes("--tailwindcss");
|
|
241
|
+
let useWebsocket = args.includes("--websocket");
|
|
242
|
+
let usePrisma = args.includes("--prisma");
|
|
243
|
+
let useDocker = args.includes("--docker");
|
|
244
|
+
const predefinedAnswers = {
|
|
245
|
+
projectName,
|
|
246
|
+
backendOnly: useBackendOnly,
|
|
247
|
+
swaggerDocs: useSwaggerDocs,
|
|
248
|
+
tailwindcss: useTailwind,
|
|
249
|
+
websocket: useWebsocket,
|
|
250
|
+
prisma: usePrisma,
|
|
251
|
+
docker: useDocker,
|
|
252
|
+
};
|
|
253
|
+
answer = await getAnswer(predefinedAnswers);
|
|
254
|
+
}
|
|
255
|
+
if (answer === null) {
|
|
256
|
+
console.log(chalk.red("Installation cancelled."));
|
|
257
|
+
return;
|
|
219
258
|
}
|
|
220
259
|
} else {
|
|
260
|
+
// No project name provided - interactive mode
|
|
221
261
|
answer = await getAnswer();
|
|
222
262
|
}
|
|
223
263
|
if (answer === null) {
|
|
@@ -273,7 +313,7 @@ async function main() {
|
|
|
273
313
|
composerPkg("ezyang/htmlpurifier"),
|
|
274
314
|
composerPkg("symfony/uid"),
|
|
275
315
|
composerPkg("brick/math"),
|
|
276
|
-
composerPkg("tsnc/prisma-php"),
|
|
316
|
+
// composerPkg("tsnc/prisma-php"),
|
|
277
317
|
];
|
|
278
318
|
if (answer.swaggerDocs) {
|
|
279
319
|
npmDependencies.push(
|
|
@@ -338,24 +378,57 @@ async function main() {
|
|
|
338
378
|
if (updateAnswer?.isUpdate) {
|
|
339
379
|
const updateUninstallNpmDependencies = [];
|
|
340
380
|
const updateUninstallComposerDependencies = [];
|
|
381
|
+
// Helper function to check if a composer package is installed
|
|
382
|
+
const isComposerPackageInstalled = (packageName) => {
|
|
383
|
+
try {
|
|
384
|
+
const composerJsonPath = path.join(projectPath, "composer.json");
|
|
385
|
+
if (fs.existsSync(composerJsonPath)) {
|
|
386
|
+
const composerJson = JSON.parse(
|
|
387
|
+
fs.readFileSync(composerJsonPath, "utf8")
|
|
388
|
+
);
|
|
389
|
+
return !!(
|
|
390
|
+
composerJson.require && composerJson.require[packageName]
|
|
391
|
+
);
|
|
392
|
+
}
|
|
393
|
+
return false;
|
|
394
|
+
} catch {
|
|
395
|
+
return false;
|
|
396
|
+
}
|
|
397
|
+
};
|
|
398
|
+
// Helper function to check if an npm package is installed
|
|
399
|
+
const isNpmPackageInstalled = (packageName) => {
|
|
400
|
+
try {
|
|
401
|
+
const packageJsonPath = path.join(projectPath, "package.json");
|
|
402
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
403
|
+
const packageJson = JSON.parse(
|
|
404
|
+
fs.readFileSync(packageJsonPath, "utf8")
|
|
405
|
+
);
|
|
406
|
+
return !!(
|
|
407
|
+
(packageJson.dependencies &&
|
|
408
|
+
packageJson.dependencies[packageName]) ||
|
|
409
|
+
(packageJson.devDependencies &&
|
|
410
|
+
packageJson.devDependencies[packageName])
|
|
411
|
+
);
|
|
412
|
+
}
|
|
413
|
+
return false;
|
|
414
|
+
} catch {
|
|
415
|
+
return false;
|
|
416
|
+
}
|
|
417
|
+
};
|
|
341
418
|
if (updateAnswer.backendOnly) {
|
|
342
419
|
nonBackendFiles.forEach((file) => {
|
|
343
420
|
const filePath = path.join(projectPath, "src", "app", file);
|
|
344
421
|
if (fs.existsSync(filePath)) {
|
|
345
|
-
fs.unlinkSync(filePath);
|
|
422
|
+
fs.unlinkSync(filePath);
|
|
346
423
|
console.log(`${file} was deleted successfully.`);
|
|
347
|
-
} else {
|
|
348
|
-
console.log(`${file} does not exist.`);
|
|
349
424
|
}
|
|
350
425
|
});
|
|
351
426
|
const backendOnlyFolders = ["js", "css"];
|
|
352
427
|
backendOnlyFolders.forEach((folder) => {
|
|
353
428
|
const folderPath = path.join(projectPath, "src", "app", folder);
|
|
354
429
|
if (fs.existsSync(folderPath)) {
|
|
355
|
-
fs.rmSync(folderPath, { recursive: true, force: true });
|
|
430
|
+
fs.rmSync(folderPath, { recursive: true, force: true });
|
|
356
431
|
console.log(`${folder} was deleted successfully.`);
|
|
357
|
-
} else {
|
|
358
|
-
console.log(`${folder} does not exist.`);
|
|
359
432
|
}
|
|
360
433
|
});
|
|
361
434
|
}
|
|
@@ -367,57 +440,61 @@ async function main() {
|
|
|
367
440
|
"swagger-docs"
|
|
368
441
|
);
|
|
369
442
|
if (fs.existsSync(swaggerDocsFolder)) {
|
|
370
|
-
fs.rmSync(swaggerDocsFolder, { recursive: true, force: true });
|
|
443
|
+
fs.rmSync(swaggerDocsFolder, { recursive: true, force: true });
|
|
371
444
|
console.log(`swagger-docs was deleted successfully.`);
|
|
372
445
|
}
|
|
373
446
|
const swaggerFiles = ["swagger-config.ts"];
|
|
374
447
|
swaggerFiles.forEach((file) => {
|
|
375
448
|
const filePath = path.join(projectPath, "settings", file);
|
|
376
449
|
if (fs.existsSync(filePath)) {
|
|
377
|
-
fs.unlinkSync(filePath);
|
|
450
|
+
fs.unlinkSync(filePath);
|
|
378
451
|
console.log(`${file} was deleted successfully.`);
|
|
379
|
-
} else {
|
|
380
|
-
console.log(`${file} does not exist.`);
|
|
381
452
|
}
|
|
382
453
|
});
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
"
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
454
|
+
// Only add to uninstall list if packages are actually installed
|
|
455
|
+
if (isNpmPackageInstalled("swagger-jsdoc")) {
|
|
456
|
+
updateUninstallNpmDependencies.push("swagger-jsdoc");
|
|
457
|
+
}
|
|
458
|
+
if (isNpmPackageInstalled("@types/swagger-jsdoc")) {
|
|
459
|
+
updateUninstallNpmDependencies.push("@types/swagger-jsdoc");
|
|
460
|
+
}
|
|
461
|
+
if (isNpmPackageInstalled("prompts")) {
|
|
462
|
+
updateUninstallNpmDependencies.push("prompts");
|
|
463
|
+
}
|
|
464
|
+
if (isNpmPackageInstalled("@types/prompts")) {
|
|
465
|
+
updateUninstallNpmDependencies.push("@types/prompts");
|
|
466
|
+
}
|
|
389
467
|
}
|
|
390
468
|
if (!updateAnswer.tailwindcss) {
|
|
391
469
|
const tailwindFiles = ["postcss.config.js"];
|
|
392
470
|
tailwindFiles.forEach((file) => {
|
|
393
471
|
const filePath = path.join(projectPath, file);
|
|
394
472
|
if (fs.existsSync(filePath)) {
|
|
395
|
-
fs.unlinkSync(filePath);
|
|
473
|
+
fs.unlinkSync(filePath);
|
|
396
474
|
console.log(`${file} was deleted successfully.`);
|
|
397
|
-
} else {
|
|
398
|
-
console.log(`${file} does not exist.`);
|
|
399
475
|
}
|
|
400
476
|
});
|
|
401
|
-
|
|
477
|
+
// Only add to uninstall list if packages are actually installed
|
|
478
|
+
const tailwindPackages = [
|
|
402
479
|
"tailwindcss",
|
|
403
480
|
"postcss",
|
|
404
481
|
"postcss-cli",
|
|
405
482
|
"@tailwindcss/postcss",
|
|
406
|
-
"cssnano"
|
|
407
|
-
|
|
483
|
+
"cssnano",
|
|
484
|
+
];
|
|
485
|
+
tailwindPackages.forEach((pkg) => {
|
|
486
|
+
if (isNpmPackageInstalled(pkg)) {
|
|
487
|
+
updateUninstallNpmDependencies.push(pkg);
|
|
488
|
+
}
|
|
489
|
+
});
|
|
408
490
|
}
|
|
409
491
|
if (!updateAnswer.websocket) {
|
|
410
|
-
const websocketFiles = [
|
|
411
|
-
"restart-websocket.ts",
|
|
412
|
-
"restart-websocket.bat",
|
|
413
|
-
];
|
|
492
|
+
const websocketFiles = ["restart-websocket.ts"];
|
|
414
493
|
websocketFiles.forEach((file) => {
|
|
415
494
|
const filePath = path.join(projectPath, "settings", file);
|
|
416
495
|
if (fs.existsSync(filePath)) {
|
|
417
|
-
fs.unlinkSync(filePath);
|
|
496
|
+
fs.unlinkSync(filePath);
|
|
418
497
|
console.log(`${file} was deleted successfully.`);
|
|
419
|
-
} else {
|
|
420
|
-
console.log(`${file} does not exist.`);
|
|
421
498
|
}
|
|
422
499
|
});
|
|
423
500
|
const websocketFolder = path.join(
|
|
@@ -427,18 +504,28 @@ async function main() {
|
|
|
427
504
|
"Websocket"
|
|
428
505
|
);
|
|
429
506
|
if (fs.existsSync(websocketFolder)) {
|
|
430
|
-
fs.rmSync(websocketFolder, { recursive: true, force: true });
|
|
507
|
+
fs.rmSync(websocketFolder, { recursive: true, force: true });
|
|
431
508
|
console.log(`Websocket folder was deleted successfully.`);
|
|
432
509
|
}
|
|
433
|
-
|
|
434
|
-
|
|
510
|
+
// Only add to uninstall list if packages are actually installed
|
|
511
|
+
if (isNpmPackageInstalled("chokidar-cli")) {
|
|
512
|
+
updateUninstallNpmDependencies.push("chokidar-cli");
|
|
513
|
+
}
|
|
514
|
+
if (isComposerPackageInstalled("cboden/ratchet")) {
|
|
515
|
+
updateUninstallComposerDependencies.push("cboden/ratchet");
|
|
516
|
+
}
|
|
435
517
|
}
|
|
436
518
|
if (!updateAnswer.prisma) {
|
|
437
|
-
|
|
519
|
+
const prismaPackages = [
|
|
438
520
|
"prisma",
|
|
439
521
|
"@prisma/client",
|
|
440
|
-
"@prisma/internals"
|
|
441
|
-
|
|
522
|
+
"@prisma/internals",
|
|
523
|
+
];
|
|
524
|
+
prismaPackages.forEach((pkg) => {
|
|
525
|
+
if (isNpmPackageInstalled(pkg)) {
|
|
526
|
+
updateUninstallNpmDependencies.push(pkg);
|
|
527
|
+
}
|
|
528
|
+
});
|
|
442
529
|
}
|
|
443
530
|
if (!updateAnswer.docker) {
|
|
444
531
|
const dockerFiles = [
|
|
@@ -450,14 +537,18 @@ async function main() {
|
|
|
450
537
|
dockerFiles.forEach((file) => {
|
|
451
538
|
const filePath = path.join(projectPath, file);
|
|
452
539
|
if (fs.existsSync(filePath)) {
|
|
453
|
-
fs.unlinkSync(filePath);
|
|
540
|
+
fs.unlinkSync(filePath);
|
|
454
541
|
console.log(`${file} was deleted successfully.`);
|
|
455
|
-
} else {
|
|
456
|
-
console.log(`${file} does not exist.`);
|
|
457
542
|
}
|
|
458
543
|
});
|
|
459
544
|
}
|
|
545
|
+
// Only uninstall if there are packages to uninstall
|
|
460
546
|
if (updateUninstallNpmDependencies.length > 0) {
|
|
547
|
+
console.log(
|
|
548
|
+
`Uninstalling npm packages: ${updateUninstallNpmDependencies.join(
|
|
549
|
+
", "
|
|
550
|
+
)}`
|
|
551
|
+
);
|
|
461
552
|
await uninstallNpmDependencies(
|
|
462
553
|
projectPath,
|
|
463
554
|
updateUninstallNpmDependencies,
|
|
@@ -465,6 +556,11 @@ async function main() {
|
|
|
465
556
|
);
|
|
466
557
|
}
|
|
467
558
|
if (updateUninstallComposerDependencies.length > 0) {
|
|
559
|
+
console.log(
|
|
560
|
+
`Uninstalling composer packages: ${updateUninstallComposerDependencies.join(
|
|
561
|
+
", "
|
|
562
|
+
)}`
|
|
563
|
+
);
|
|
468
564
|
await uninstallComposerDependencies(
|
|
469
565
|
projectPath,
|
|
470
566
|
updateUninstallComposerDependencies
|
|
@@ -478,7 +574,6 @@ async function main() {
|
|
|
478
574
|
projectRootPath: projectPathModified,
|
|
479
575
|
phpEnvironment: "XAMPP",
|
|
480
576
|
phpRootPathExe: "C:\\xampp\\php\\php.exe",
|
|
481
|
-
phpGenerateClassPath: "src/Lib/Prisma/Classes",
|
|
482
577
|
bsTarget: bsConfig.bsTarget,
|
|
483
578
|
bsPathRewrite: bsConfig.bsPathRewrite,
|
|
484
579
|
backendOnly: answer.backendOnly,
|