feat(create-medusa-app): Add a --verbose option. (#6027)
## What Adds a `--verbose` option that shows the output of all underlying processes in real-time. ## Why This is helpful for testing and debugging issues, especially issues that the community runs into. We can ask community members to pass the `--verbose` option and provide us with the outputted logs if they face problems. ## Caveats When installing the Next.js starter then terminating the process, the main and child processes don't receive the abort signal as it seems to occur in the child process. This leads to the command continuing but then running into an error in the next step. As this option is only used for debugging, I don't think it's a big issue. ## Testing Run the `create-medusa-app` snapshot below with `--verbose` option. Or, change to the `packages/create-medusa-app` directory and run: ```bash yarn dev --directory-path ~/some-dir --verbose ``` > The `--directory-path` option in this case is necessary as installing the medusa backend in the current `packages/create-medusa-app` directory leads to errors related to yarn workspaces.
This commit is contained in:
5
.changeset/three-mice-jump.md
Normal file
5
.changeset/three-mice-jump.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"create-medusa-app": patch
|
||||
---
|
||||
|
||||
feat(create-medusa-app): Add a `--verbose` option.
|
||||
@@ -42,6 +42,7 @@ export type CreateOptions = {
|
||||
migrations?: boolean
|
||||
directoryPath?: string
|
||||
withNextjsStarter?: boolean
|
||||
verbose?: boolean
|
||||
v2?: boolean
|
||||
}
|
||||
|
||||
@@ -55,6 +56,7 @@ export default async ({
|
||||
migrations,
|
||||
directoryPath,
|
||||
withNextjsStarter = false,
|
||||
verbose = false,
|
||||
v2 = false,
|
||||
}: CreateOptions) => {
|
||||
track("CREATE_CLI_CMA")
|
||||
@@ -68,6 +70,7 @@ export default async ({
|
||||
processManager,
|
||||
message: "",
|
||||
title: "",
|
||||
verbose,
|
||||
}
|
||||
const dbName = !skipDb && !dbUrl ? `medusa-${nanoid(4)}` : ""
|
||||
let isProjectCreated = false
|
||||
@@ -103,6 +106,7 @@ export default async ({
|
||||
? await getDbClientAndCredentials({
|
||||
dbName,
|
||||
dbUrl,
|
||||
verbose,
|
||||
})
|
||||
: { client: null, dbConnectionString: "" }
|
||||
isDbInitialized = true
|
||||
@@ -115,6 +119,7 @@ export default async ({
|
||||
browser,
|
||||
migrations,
|
||||
installNextjs,
|
||||
verbose,
|
||||
})
|
||||
|
||||
logMessage({
|
||||
@@ -136,6 +141,7 @@ export default async ({
|
||||
repoUrl,
|
||||
abortController,
|
||||
spinner,
|
||||
verbose,
|
||||
v2,
|
||||
})
|
||||
} catch {
|
||||
@@ -152,6 +158,7 @@ export default async ({
|
||||
directoryName: projectPath,
|
||||
abortController,
|
||||
factBoxOptions,
|
||||
verbose,
|
||||
})
|
||||
: ""
|
||||
|
||||
@@ -187,6 +194,7 @@ export default async ({
|
||||
onboardingType: installNextjs ? "nextjs" : "default",
|
||||
nextjsDirectory,
|
||||
client,
|
||||
verbose,
|
||||
v2,
|
||||
})
|
||||
} catch (e: any) {
|
||||
@@ -225,9 +233,10 @@ export default async ({
|
||||
})
|
||||
|
||||
if (installNextjs && nextjsDirectory) {
|
||||
void startNextjsStarter({
|
||||
startNextjsStarter({
|
||||
directory: nextjsDirectory,
|
||||
abortController,
|
||||
verbose,
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
|
||||
@@ -38,6 +38,11 @@ program
|
||||
"Install the Next.js starter along with the Medusa backend",
|
||||
false
|
||||
)
|
||||
.option(
|
||||
"--verbose",
|
||||
"Show all logs of underlying commands. Useful for debugging.",
|
||||
false
|
||||
)
|
||||
.option(
|
||||
"--v2",
|
||||
"Install Medusa with the V2 feature flag enabled. WARNING: Medusa V2 is still in development and shouldn't be used in production.",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import promiseExec from "./promise-exec.js"
|
||||
import execute from "./execute.js"
|
||||
import { Ora } from "ora"
|
||||
import { isAbortError } from "./create-abort-controller.js"
|
||||
import logMessage from "./log-message.js"
|
||||
@@ -9,6 +9,7 @@ type CloneRepoOptions = {
|
||||
directoryName?: string
|
||||
repoUrl?: string
|
||||
abortController?: AbortController
|
||||
verbose?: boolean
|
||||
v2?: boolean
|
||||
}
|
||||
|
||||
@@ -19,15 +20,19 @@ export default async function cloneRepo({
|
||||
directoryName = "",
|
||||
repoUrl,
|
||||
abortController,
|
||||
verbose = false,
|
||||
v2 = false,
|
||||
}: CloneRepoOptions) {
|
||||
await promiseExec(
|
||||
`git clone ${repoUrl || DEFAULT_REPO}${
|
||||
v2 ? ` -b ${V2_BRANCH}` : ""
|
||||
} ${directoryName}`,
|
||||
{
|
||||
signal: abortController?.signal,
|
||||
}
|
||||
await execute(
|
||||
[
|
||||
`git clone ${repoUrl || DEFAULT_REPO}${
|
||||
v2 ? ` -b ${V2_BRANCH}` : ""
|
||||
} ${directoryName}`,
|
||||
{
|
||||
signal: abortController?.signal,
|
||||
},
|
||||
],
|
||||
{ verbose }
|
||||
)
|
||||
}
|
||||
|
||||
@@ -36,12 +41,14 @@ export async function runCloneRepo({
|
||||
repoUrl,
|
||||
abortController,
|
||||
spinner,
|
||||
verbose = false,
|
||||
v2 = false,
|
||||
}: {
|
||||
projectName: string
|
||||
repoUrl: string
|
||||
abortController: AbortController
|
||||
spinner: Ora
|
||||
verbose?: boolean
|
||||
v2?: boolean
|
||||
}) {
|
||||
try {
|
||||
@@ -49,6 +56,7 @@ export async function runCloneRepo({
|
||||
directoryName: projectName,
|
||||
repoUrl,
|
||||
abortController,
|
||||
verbose,
|
||||
v2,
|
||||
})
|
||||
|
||||
|
||||
@@ -8,3 +8,9 @@ export default (processManager: ProcessManager) => {
|
||||
|
||||
export const isAbortError = (e: any) =>
|
||||
e !== null && "code" in e && e.code === "ABORT_ERR"
|
||||
|
||||
export const getAbortError = () => {
|
||||
return {
|
||||
code: "ABORT_ERR",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,13 @@ export async function runCreateDb({
|
||||
return newClient
|
||||
}
|
||||
|
||||
async function getForDbName(dbName: string): Promise<{
|
||||
async function getForDbName({
|
||||
dbName,
|
||||
verbose = false,
|
||||
}: {
|
||||
dbName: string
|
||||
verbose?: boolean
|
||||
}): Promise<{
|
||||
client: pg.Client
|
||||
dbConnectionString: string
|
||||
}> {
|
||||
@@ -66,6 +72,12 @@ async function getForDbName(dbName: string): Promise<{
|
||||
password: postgresPassword,
|
||||
})
|
||||
} catch (e) {
|
||||
if (verbose) {
|
||||
logMessage({
|
||||
message: `The following error occured when connecting to the database: ${e}`,
|
||||
type: "verbose",
|
||||
})
|
||||
}
|
||||
// ask for the user's postgres credentials
|
||||
const answers = await inquirer.prompt([
|
||||
{
|
||||
@@ -114,7 +126,13 @@ async function getForDbName(dbName: string): Promise<{
|
||||
}
|
||||
}
|
||||
|
||||
async function getForDbUrl(dbUrl: string): Promise<{
|
||||
async function getForDbUrl({
|
||||
dbUrl,
|
||||
verbose = false,
|
||||
}: {
|
||||
dbUrl: string
|
||||
verbose?: boolean
|
||||
}): Promise<{
|
||||
client: pg.Client
|
||||
dbConnectionString: string
|
||||
}> {
|
||||
@@ -125,6 +143,12 @@ async function getForDbUrl(dbUrl: string): Promise<{
|
||||
connectionString: dbUrl,
|
||||
})
|
||||
} catch (e) {
|
||||
if (verbose) {
|
||||
logMessage({
|
||||
message: `The following error occured when connecting to the database: ${e}`,
|
||||
type: "verbose",
|
||||
})
|
||||
}
|
||||
logMessage({
|
||||
message: `Couldn't connect to PostgreSQL using the database URL you passed. Make sure it's correct and try again.`,
|
||||
type: "error",
|
||||
@@ -140,13 +164,21 @@ async function getForDbUrl(dbUrl: string): Promise<{
|
||||
export async function getDbClientAndCredentials({
|
||||
dbName = "",
|
||||
dbUrl = "",
|
||||
verbose = false,
|
||||
}): Promise<{
|
||||
client: pg.Client
|
||||
dbConnectionString: string
|
||||
verbose?: boolean
|
||||
}> {
|
||||
if (dbName) {
|
||||
return await getForDbName(dbName)
|
||||
return await getForDbName({
|
||||
dbName,
|
||||
verbose,
|
||||
})
|
||||
} else {
|
||||
return await getForDbUrl(dbUrl)
|
||||
return await getForDbUrl({
|
||||
dbUrl,
|
||||
verbose,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
72
packages/create-medusa-app/src/utils/execute.ts
Normal file
72
packages/create-medusa-app/src/utils/execute.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
import { exec, spawnSync, SpawnSyncOptions } from "child_process"
|
||||
import util from "util"
|
||||
import { getAbortError } from "./create-abort-controller.js"
|
||||
|
||||
const promiseExec = util.promisify(exec)
|
||||
|
||||
type ExecuteOptions = {
|
||||
stdout?: string
|
||||
stderr?: string
|
||||
}
|
||||
|
||||
type VerboseOptions = {
|
||||
verbose?: boolean
|
||||
// Since spawn doesn't allow us to both retrieve the
|
||||
// output and output it live without using events,
|
||||
// enabling this option, which is only useful if `verbose` is `true`,
|
||||
// defers the output of the process until after the process is executed
|
||||
// instead of outputting the log in realtime, which is the default.
|
||||
// it prioritizes retrieving the output over outputting it in real-time.
|
||||
needOutput?: boolean
|
||||
}
|
||||
|
||||
type PromiseExecParams = Parameters<typeof promiseExec>
|
||||
type SpawnParams = [string, SpawnSyncOptions]
|
||||
|
||||
const execute = async (
|
||||
command: SpawnParams | PromiseExecParams,
|
||||
{ verbose = false, needOutput = false }: VerboseOptions
|
||||
): Promise<ExecuteOptions> => {
|
||||
if (verbose) {
|
||||
const [commandStr, options] = command as SpawnParams
|
||||
const childProcess = spawnSync(commandStr, {
|
||||
...options,
|
||||
shell: true,
|
||||
stdio: needOutput
|
||||
? "pipe"
|
||||
: [process.stdin, process.stdout, process.stderr],
|
||||
})
|
||||
|
||||
if (childProcess.error) {
|
||||
throw childProcess.error
|
||||
}
|
||||
|
||||
if (
|
||||
childProcess.signal &&
|
||||
["SIGINT", "SIGTERM"].includes(childProcess.signal)
|
||||
) {
|
||||
console.log("abortingggg")
|
||||
throw getAbortError()
|
||||
}
|
||||
|
||||
if (needOutput) {
|
||||
console.log(
|
||||
childProcess.stdout?.toString() || childProcess.stderr?.toString()
|
||||
)
|
||||
}
|
||||
|
||||
return {
|
||||
stdout: childProcess.stdout?.toString() || "",
|
||||
stderr: childProcess.stderr?.toString() || "",
|
||||
}
|
||||
} else {
|
||||
const childProcess = await promiseExec(...(command as PromiseExecParams))
|
||||
|
||||
return {
|
||||
stdout: childProcess.stdout as string,
|
||||
stderr: childProcess.stderr as string,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default execute
|
||||
@@ -10,6 +10,7 @@ export type FactBoxOptions = {
|
||||
processManager: ProcessManager
|
||||
message?: string
|
||||
title?: string
|
||||
verbose?: boolean
|
||||
}
|
||||
|
||||
const facts = [
|
||||
@@ -38,25 +39,41 @@ export const getFact = () => {
|
||||
return facts[randIndex]
|
||||
}
|
||||
|
||||
export const showFact = (spinner: Ora, title: string) => {
|
||||
export const showFact = ({
|
||||
spinner,
|
||||
title,
|
||||
verbose,
|
||||
}: Pick<FactBoxOptions, "spinner" | "verbose"> & {
|
||||
title: string
|
||||
}) => {
|
||||
const fact = getFact()
|
||||
spinner.text = `${title}\n${boxen(`${fact}`, {
|
||||
title: chalk.cyan(`${emojify(":bulb:")} Medusa Tips`),
|
||||
titleAlignment: "center",
|
||||
textAlignment: "center",
|
||||
padding: 1,
|
||||
margin: 1,
|
||||
})}`
|
||||
if (verbose) {
|
||||
spinner.stopAndPersist({
|
||||
symbol: chalk.cyan("⠋"),
|
||||
text: title,
|
||||
})
|
||||
} else {
|
||||
spinner.text = `${title}\n${boxen(`${fact}`, {
|
||||
title: chalk.cyan(`${emojify(":bulb:")} Medusa Tips`),
|
||||
titleAlignment: "center",
|
||||
textAlignment: "center",
|
||||
padding: 1,
|
||||
margin: 1,
|
||||
})}`
|
||||
}
|
||||
}
|
||||
|
||||
export const createFactBox = (
|
||||
spinner: Ora,
|
||||
title: string,
|
||||
processManager: ProcessManager
|
||||
): NodeJS.Timeout => {
|
||||
showFact(spinner, title)
|
||||
export const createFactBox = ({
|
||||
spinner,
|
||||
title,
|
||||
processManager,
|
||||
verbose,
|
||||
}: Pick<FactBoxOptions, "spinner" | "processManager" | "verbose"> & {
|
||||
title: string
|
||||
}): NodeJS.Timeout => {
|
||||
showFact({ spinner, title, verbose })
|
||||
const interval = setInterval(() => {
|
||||
showFact(spinner, title)
|
||||
showFact({ spinner, title, verbose })
|
||||
}, 10000)
|
||||
|
||||
processManager.addInterval(interval)
|
||||
@@ -64,13 +81,20 @@ export const createFactBox = (
|
||||
return interval
|
||||
}
|
||||
|
||||
export const resetFactBox = (
|
||||
interval: NodeJS.Timeout | null,
|
||||
spinner: Ora,
|
||||
successMessage: string,
|
||||
processManager: ProcessManager,
|
||||
export const resetFactBox = ({
|
||||
interval,
|
||||
spinner,
|
||||
successMessage,
|
||||
processManager,
|
||||
newTitle,
|
||||
verbose,
|
||||
}: Pick<
|
||||
FactBoxOptions,
|
||||
"interval" | "spinner" | "processManager" | "verbose"
|
||||
> & {
|
||||
successMessage: string
|
||||
newTitle?: string
|
||||
): NodeJS.Timeout | null => {
|
||||
}): NodeJS.Timeout | null => {
|
||||
if (interval) {
|
||||
clearInterval(interval)
|
||||
}
|
||||
@@ -78,7 +102,12 @@ export const resetFactBox = (
|
||||
spinner.succeed(chalk.green(successMessage)).start()
|
||||
let newInterval = null
|
||||
if (newTitle) {
|
||||
newInterval = createFactBox(spinner, newTitle, processManager)
|
||||
newInterval = createFactBox({
|
||||
spinner,
|
||||
title: newTitle,
|
||||
processManager,
|
||||
verbose,
|
||||
})
|
||||
}
|
||||
|
||||
return newInterval
|
||||
@@ -90,10 +119,18 @@ export function displayFactBox({
|
||||
processManager,
|
||||
title = "",
|
||||
message = "",
|
||||
verbose = false,
|
||||
}: FactBoxOptions): NodeJS.Timeout | null {
|
||||
if (!message) {
|
||||
return createFactBox(spinner, title, processManager)
|
||||
return createFactBox({ spinner, title, processManager, verbose })
|
||||
}
|
||||
|
||||
return resetFactBox(interval, spinner, message, processManager, title)
|
||||
return resetFactBox({
|
||||
interval,
|
||||
spinner,
|
||||
successMessage: message,
|
||||
processManager,
|
||||
newTitle: title,
|
||||
verbose,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import { logger } from "./logger.js"
|
||||
|
||||
type LogOptions = {
|
||||
message: string
|
||||
type?: "error" | "success" | "info" | "warning"
|
||||
type?: "error" | "success" | "info" | "warning" | "verbose"
|
||||
}
|
||||
|
||||
export default ({ message, type = "info" }: LogOptions) => {
|
||||
@@ -18,6 +18,9 @@ export default ({ message, type = "info" }: LogOptions) => {
|
||||
case "warning":
|
||||
logger.warning(chalk.yellow(message))
|
||||
break
|
||||
case "verbose":
|
||||
logger.info(`${chalk.bgYellowBright("VERBOSE LOG:")} ${message}`)
|
||||
break
|
||||
case "error":
|
||||
program.error(chalk.bold.red(message))
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import inquirer from "inquirer"
|
||||
import promiseExec from "./promise-exec.js"
|
||||
import { exec } from "child_process"
|
||||
import execute from "./execute.js"
|
||||
import { FactBoxOptions, displayFactBox } from "./facts.js"
|
||||
import fs from "fs"
|
||||
import path from "path"
|
||||
import { customAlphabet, nanoid } from "nanoid"
|
||||
import { customAlphabet } from "nanoid"
|
||||
import { isAbortError } from "./create-abort-controller.js"
|
||||
import logMessage from "./log-message.js"
|
||||
|
||||
@@ -26,12 +27,14 @@ type InstallOptions = {
|
||||
directoryName: string
|
||||
abortController?: AbortController
|
||||
factBoxOptions: FactBoxOptions
|
||||
verbose?: boolean
|
||||
}
|
||||
|
||||
export async function installNextjsStarter({
|
||||
directoryName,
|
||||
abortController,
|
||||
factBoxOptions,
|
||||
verbose = false,
|
||||
}: InstallOptions): Promise<string> {
|
||||
factBoxOptions.interval = displayFactBox({
|
||||
...factBoxOptions,
|
||||
@@ -53,15 +56,18 @@ export async function installNextjsStarter({
|
||||
}
|
||||
|
||||
try {
|
||||
await promiseExec(
|
||||
`npx create-next-app -e ${NEXTJS_REPO} ${nextjsDirectory}`,
|
||||
{
|
||||
signal: abortController?.signal,
|
||||
env: {
|
||||
...process.env,
|
||||
npm_config_yes: "yes",
|
||||
await execute(
|
||||
[
|
||||
`npx create-next-app -e ${NEXTJS_REPO} ${nextjsDirectory}`,
|
||||
{
|
||||
signal: abortController?.signal,
|
||||
env: {
|
||||
...process.env,
|
||||
npm_config_yes: "yes",
|
||||
},
|
||||
},
|
||||
}
|
||||
],
|
||||
{ verbose }
|
||||
)
|
||||
} catch (e) {
|
||||
if (isAbortError(e)) {
|
||||
@@ -90,18 +96,21 @@ export async function installNextjsStarter({
|
||||
type StartOptions = {
|
||||
directory: string
|
||||
abortController?: AbortController
|
||||
verbose?: boolean
|
||||
}
|
||||
|
||||
export async function startNextjsStarter({
|
||||
export function startNextjsStarter({
|
||||
directory,
|
||||
abortController,
|
||||
verbose = false,
|
||||
}: StartOptions) {
|
||||
try {
|
||||
await promiseExec(`npm run dev`, {
|
||||
cwd: directory,
|
||||
signal: abortController?.signal,
|
||||
})
|
||||
} catch {
|
||||
// ignore abort errors
|
||||
const childProcess = exec(`npm run dev`, {
|
||||
cwd: directory,
|
||||
signal: abortController?.signal,
|
||||
})
|
||||
|
||||
if (verbose) {
|
||||
childProcess.stdout?.pipe(process.stdout)
|
||||
childProcess.stderr?.pipe(process.stderr)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import chalk from "chalk"
|
||||
import fs from "fs"
|
||||
import path from "path"
|
||||
import { Ora } from "ora"
|
||||
import promiseExec from "./promise-exec.js"
|
||||
import execute from "./execute.js"
|
||||
import { EOL } from "os"
|
||||
import { displayFactBox, FactBoxOptions } from "./facts.js"
|
||||
import ProcessManager from "./process-manager.js"
|
||||
@@ -25,6 +25,7 @@ type PrepareOptions = {
|
||||
onboardingType?: "default" | "nextjs"
|
||||
nextjsDirectory?: string
|
||||
client: Client | null
|
||||
verbose?: boolean
|
||||
v2?: boolean
|
||||
}
|
||||
|
||||
@@ -42,6 +43,7 @@ export default async ({
|
||||
onboardingType = "default",
|
||||
nextjsDirectory = "",
|
||||
client,
|
||||
verbose = false,
|
||||
v2 = false,
|
||||
}: PrepareOptions) => {
|
||||
// initialize execution options
|
||||
@@ -64,6 +66,7 @@ export default async ({
|
||||
processManager,
|
||||
message: "",
|
||||
title: "",
|
||||
verbose,
|
||||
}
|
||||
|
||||
// initialize the invite token to return
|
||||
@@ -91,11 +94,13 @@ export default async ({
|
||||
await processManager.runProcess({
|
||||
process: async () => {
|
||||
try {
|
||||
await promiseExec(`yarn`, execOptions)
|
||||
await execute([`yarn`, execOptions], { verbose })
|
||||
} catch (e) {
|
||||
// yarn isn't available
|
||||
// use npm
|
||||
await promiseExec(`npm install --legacy-peer-deps`, execOptions)
|
||||
await execute([`npm install --legacy-peer-deps`, execOptions], {
|
||||
verbose,
|
||||
})
|
||||
}
|
||||
},
|
||||
ignoreERESOLVE: true,
|
||||
@@ -127,11 +132,11 @@ export default async ({
|
||||
await processManager.runProcess({
|
||||
process: async () => {
|
||||
try {
|
||||
await promiseExec(`yarn build`, execOptions)
|
||||
await execute([`yarn build`, execOptions], { verbose })
|
||||
} catch (e) {
|
||||
// yarn isn't available
|
||||
// use npm
|
||||
await promiseExec(`npm run build`, execOptions)
|
||||
await execute([`npm run build`, execOptions], { verbose })
|
||||
}
|
||||
},
|
||||
ignoreERESOLVE: true,
|
||||
@@ -148,9 +153,9 @@ export default async ({
|
||||
// run migrations
|
||||
await processManager.runProcess({
|
||||
process: async () => {
|
||||
const proc = await promiseExec(
|
||||
"npx @medusajs/medusa-cli@latest migrations run",
|
||||
npxOptions
|
||||
const proc = await execute(
|
||||
["npx @medusajs/medusa-cli@latest migrations run", npxOptions],
|
||||
{ verbose, needOutput: true }
|
||||
)
|
||||
|
||||
if (client) {
|
||||
@@ -169,7 +174,7 @@ export default async ({
|
||||
}
|
||||
|
||||
// ensure that migrations actually ran in case of an uncaught error
|
||||
if (errorOccurred) {
|
||||
if (errorOccurred && (proc.stderr || proc.stdout)) {
|
||||
throw new Error(
|
||||
`An error occurred while running migrations: ${
|
||||
proc.stderr || proc.stdout
|
||||
@@ -195,12 +200,18 @@ export default async ({
|
||||
|
||||
await processManager.runProcess({
|
||||
process: async () => {
|
||||
const proc = await promiseExec(
|
||||
`npx @medusajs/medusa-cli@latest user -e ${admin.email} --invite`,
|
||||
npxOptions
|
||||
const proc = await execute(
|
||||
[
|
||||
`npx @medusajs/medusa-cli@latest user -e ${admin.email} --invite`,
|
||||
npxOptions,
|
||||
],
|
||||
{ verbose, needOutput: true }
|
||||
)
|
||||
|
||||
// get invite token from stdout
|
||||
const match = proc.stdout.match(/Invite token: (?<token>.+)/)
|
||||
const match = (proc.stdout as string).match(
|
||||
/Invite token: (?<token>.+)/
|
||||
)
|
||||
inviteToken = match?.groups?.token
|
||||
},
|
||||
})
|
||||
@@ -232,12 +243,15 @@ export default async ({
|
||||
|
||||
await processManager.runProcess({
|
||||
process: async () => {
|
||||
await promiseExec(
|
||||
`npx @medusajs/medusa-cli@latest seed --seed-file=${path.join(
|
||||
"data",
|
||||
"seed.json"
|
||||
)}`,
|
||||
npxOptions
|
||||
await execute(
|
||||
[
|
||||
`npx @medusajs/medusa-cli@latest seed --seed-file=${path.join(
|
||||
"data",
|
||||
"seed.json"
|
||||
)}`,
|
||||
npxOptions,
|
||||
],
|
||||
{ verbose }
|
||||
)
|
||||
},
|
||||
})
|
||||
@@ -257,12 +271,15 @@ export default async ({
|
||||
|
||||
await processManager.runProcess({
|
||||
process: async () => {
|
||||
await promiseExec(
|
||||
`npx @medusajs/medusa-cli@latest seed --seed-file=${path.join(
|
||||
"data",
|
||||
"seed-onboarding.json"
|
||||
)}`,
|
||||
npxOptions
|
||||
await execute(
|
||||
[
|
||||
`npx @medusajs/medusa-cli@latest seed --seed-file=${path.join(
|
||||
"data",
|
||||
"seed-onboarding.json"
|
||||
)}`,
|
||||
npxOptions,
|
||||
],
|
||||
{ verbose }
|
||||
)
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
import { exec } from "child_process"
|
||||
import util from "util"
|
||||
|
||||
const promiseExec = util.promisify(exec)
|
||||
|
||||
export default promiseExec
|
||||
@@ -17,4 +17,5 @@ export default ({ directory, abortController }: StartOptions) => {
|
||||
})
|
||||
|
||||
childProcess.stdout?.pipe(process.stdout)
|
||||
childProcess.stderr?.pipe(process.stderr)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user