feat(create-medusa-app): add install Next.js storefront option (#4968)

* feat(create-medusa-app): add install Next.js storefront option

* added config for yes option

* added more instructions to exit message

* handle duplicate directories and next errors

* use next.js branch

* add line break in storefront question

* pass next.js directory name as env variable

* change question message

* address PR feedback

* fix(medusa-cli): remove .git directory in `new` command

* fix deleting a directory error
This commit is contained in:
Shahed Nasser
2023-09-08 12:17:48 +02:00
committed by GitHub
parent aecae5705d
commit 240b038006
7 changed files with 172 additions and 9 deletions
@@ -0,0 +1,107 @@
import inquirer from "inquirer"
import promiseExec from "./promise-exec.js"
import { FactBoxOptions, displayFactBox } from "./facts.js"
import fs from "fs"
import { customAlphabet, nanoid } from "nanoid"
import { isAbortError } from "./create-abort-controller.js"
import logMessage from "./log-message.js"
import { EOL } from "os"
const NEXTJS_REPO = "https://github.com/medusajs/nextjs-starter-medusa"
export async function askForNextjsStarter(): Promise<boolean> {
const { installNextjs } = await inquirer.prompt([
{
type: "confirm",
name: "installNextjs",
message: `Would you like to create the Next.js storefront? You can also create it later`,
default: false,
},
])
return installNextjs
}
type InstallOptions = {
directoryName: string
abortController?: AbortController
factBoxOptions: FactBoxOptions
}
export async function installNextjsStarter({
directoryName,
abortController,
factBoxOptions,
}: InstallOptions): Promise<string> {
factBoxOptions.interval = displayFactBox({
...factBoxOptions,
title: "Installing Next.js Storefront...",
})
let nextjsDirectory = `${directoryName}-storefront`
if (
fs.existsSync(nextjsDirectory) &&
fs.lstatSync(nextjsDirectory).isDirectory()
) {
// append a random number to the directory name
nextjsDirectory += `-${customAlphabet(
// npm throws an error if the directory name has an uppercase letter
"123456789abcdefghijklmnopqrstuvwxyz",
4
)()}`
}
try {
await promiseExec(
`npx create-next-app -e ${NEXTJS_REPO} ${nextjsDirectory}`,
{
signal: abortController?.signal,
env: {
...process.env,
npm_config_yes: "yes",
},
}
)
} catch (e) {
if (isAbortError(e)) {
process.exit()
}
logMessage({
message: `An error occurred while installing Next.js storefront: ${e}`,
type: "error",
})
}
await promiseExec(`mv .env.template .env.local`, {
cwd: nextjsDirectory,
signal: abortController?.signal,
})
displayFactBox({
...factBoxOptions,
message: `Installed Next.js Starter successfully in the ${nextjsDirectory} directory.`,
})
return nextjsDirectory
}
type StartOptions = {
directory: string
abortController?: AbortController
}
export async function startNextjsStarter({
directory,
abortController,
}: StartOptions) {
try {
await promiseExec(`npm run dev`, {
cwd: directory,
signal: abortController?.signal,
})
} catch {
// ignore abort errors
}
}
@@ -21,6 +21,8 @@ type PrepareOptions = {
abortController?: AbortController
skipDb?: boolean
migrations?: boolean
onboardingType?: "default" | "nextjs"
nextjsDirectory?: string
}
export default async ({
@@ -34,6 +36,8 @@ export default async ({
abortController,
skipDb,
migrations,
onboardingType = "default",
nextjsDirectory = "",
}: PrepareOptions) => {
// initialize execution options
const execOptions = {
@@ -61,11 +65,12 @@ export default async ({
let inviteToken: string | undefined = undefined
if (!skipDb) {
let env = `DATABASE_TYPE=postgres${EOL}DATABASE_URL=${dbConnectionString}${EOL}MEDUSA_ADMIN_ONBOARDING_TYPE=${onboardingType}${EOL}STORE_CORS=http://localhost:8000,http://localhost:7001`
if (nextjsDirectory) {
env += `${EOL}MEDUSA_ADMIN_ONBOARDING_NEXTJS_DIRECTORY=${nextjsDirectory}`
}
// add connection string to project
fs.appendFileSync(
path.join(directory, `.env`),
`DATABASE_TYPE=postgres${EOL}DATABASE_URL=${dbConnectionString}`
)
fs.appendFileSync(path.join(directory, `.env`), env)
}
factBoxOptions.interval = displayFactBox({