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:
@@ -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({
|
||||
|
||||
Reference in New Issue
Block a user