feature: add db:setup command (#8830)
This commit is contained in:
@@ -120,6 +120,42 @@ function buildLocalCommands(cli, isLocalProject) {
|
||||
desc: `Create a new Medusa project.`,
|
||||
handler: handlerP(newStarter),
|
||||
})
|
||||
.command({
|
||||
command: "db:setup",
|
||||
desc: "Create the database, run migrations and sync links",
|
||||
builder: (builder) => {
|
||||
builder.option("db", {
|
||||
type: "string",
|
||||
describe: "Specify the name of the database you want to create",
|
||||
})
|
||||
builder.option("interactive", {
|
||||
type: "boolean",
|
||||
default: true,
|
||||
describe:
|
||||
"Display prompts. Use --no-interactive flag to run the command without prompts",
|
||||
})
|
||||
builder.option("skip-links", {
|
||||
type: "boolean",
|
||||
describe: "Do not sync links",
|
||||
})
|
||||
builder.option("execute-all-links", {
|
||||
type: "boolean",
|
||||
describe:
|
||||
"Skip prompts and execute all (including unsafe) actions from sync links",
|
||||
})
|
||||
builder.option("execute-safe-links", {
|
||||
type: "boolean",
|
||||
describe:
|
||||
"Skip prompts and execute only safe actions from sync links",
|
||||
})
|
||||
},
|
||||
handler: handlerP(
|
||||
getCommandHandler("db/setup", (args, cmd) => {
|
||||
process.env.NODE_ENV = process.env.NODE_ENV || `development`
|
||||
return cmd(args)
|
||||
})
|
||||
),
|
||||
})
|
||||
.command({
|
||||
command: "db:create",
|
||||
desc: "Create the database used by your application",
|
||||
|
||||
@@ -10,7 +10,19 @@ import {
|
||||
parseConnectionString,
|
||||
} from "@medusajs/utils"
|
||||
|
||||
const main = async function ({ directory, interactive, db }) {
|
||||
/**
|
||||
* A low-level utility to create the database. This util should
|
||||
* never exit the process implicitly.
|
||||
*/
|
||||
export async function dbCreate({
|
||||
db,
|
||||
directory,
|
||||
interactive,
|
||||
}: {
|
||||
db: string | undefined
|
||||
directory: string
|
||||
interactive: boolean
|
||||
}): Promise<boolean> {
|
||||
let dbName = db
|
||||
|
||||
/**
|
||||
@@ -33,8 +45,7 @@ const main = async function ({ directory, interactive, db }) {
|
||||
logger.error(
|
||||
`Missing "DATABASE_URL" inside the .env file. The value is required to connect to the PostgreSQL server`
|
||||
)
|
||||
process.exitCode = 1
|
||||
return
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -45,18 +56,11 @@ const main = async function ({ directory, interactive, db }) {
|
||||
const defaultValue =
|
||||
envEditor.get("DB_NAME") ?? `medusa-${slugify(basename(directory))}`
|
||||
if (interactive) {
|
||||
try {
|
||||
dbName = await input({
|
||||
message: "Enter the database name",
|
||||
default: defaultValue,
|
||||
required: true,
|
||||
})
|
||||
} catch (error) {
|
||||
if (error.name === "ExitPromptError") {
|
||||
process.exit()
|
||||
}
|
||||
throw error
|
||||
}
|
||||
dbName = await input({
|
||||
message: "Enter the database name",
|
||||
default: defaultValue,
|
||||
required: true,
|
||||
})
|
||||
} else {
|
||||
dbName = defaultValue
|
||||
}
|
||||
@@ -82,12 +86,11 @@ const main = async function ({ directory, interactive, db }) {
|
||||
await client.connect()
|
||||
logger.info(`Connection established with the database "${dbName}"`)
|
||||
} catch (error) {
|
||||
process.exitCode = 1
|
||||
logger.error(
|
||||
"Unable to establish database connection because of the following error"
|
||||
)
|
||||
logger.error(error)
|
||||
return
|
||||
return false
|
||||
}
|
||||
|
||||
if (await dbExists(client, dbName)) {
|
||||
@@ -97,7 +100,7 @@ const main = async function ({ directory, interactive, db }) {
|
||||
await envEditor.save()
|
||||
logger.info(`Updated .env file with "DB_NAME=${dbName}"`)
|
||||
|
||||
return
|
||||
return true
|
||||
}
|
||||
|
||||
await createDb(client, dbName)
|
||||
@@ -106,6 +109,20 @@ const main = async function ({ directory, interactive, db }) {
|
||||
envEditor.set("DB_NAME", dbName)
|
||||
await envEditor.save()
|
||||
logger.info(`Updated .env file with "DB_NAME=${dbName}"`)
|
||||
return true
|
||||
}
|
||||
|
||||
const main = async function ({ directory, interactive, db }) {
|
||||
try {
|
||||
const created = await dbCreate({ directory, interactive, db })
|
||||
process.exit(created ? 0 : 1)
|
||||
} catch (error) {
|
||||
if (error.name === "ExitPromptError") {
|
||||
process.exit()
|
||||
}
|
||||
logger.error(error)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
export default main
|
||||
|
||||
@@ -9,6 +9,62 @@ import { getResolvedPlugins } from "../../loaders/helpers/resolve-plugins"
|
||||
|
||||
const TERMINAL_SIZE = process.stdout.columns
|
||||
|
||||
/**
|
||||
* A low-level utility to migrate the database. This util should
|
||||
* never exit the process implicitly.
|
||||
*/
|
||||
export async function migrate({
|
||||
directory,
|
||||
skipLinks,
|
||||
executeAllLinks,
|
||||
executeSafeLinks,
|
||||
}: {
|
||||
directory: string
|
||||
skipLinks: boolean
|
||||
executeAllLinks: boolean
|
||||
executeSafeLinks: boolean
|
||||
}): Promise<boolean> {
|
||||
/**
|
||||
* Setup
|
||||
*/
|
||||
const container = await initializeContainer(directory)
|
||||
await ensureDbExists(container)
|
||||
|
||||
const medusaAppLoader = new MedusaAppLoader()
|
||||
const configModule = container.resolve(
|
||||
ContainerRegistrationKeys.CONFIG_MODULE
|
||||
)
|
||||
|
||||
const plugins = getResolvedPlugins(directory, configModule, true) || []
|
||||
const linksSourcePaths = plugins.map((plugin) =>
|
||||
join(plugin.resolve, "links")
|
||||
)
|
||||
await new LinkLoader(linksSourcePaths).load()
|
||||
|
||||
/**
|
||||
* Run migrations
|
||||
*/
|
||||
logger.info("Running migrations...")
|
||||
await medusaAppLoader.runModulesMigrations({
|
||||
action: "run",
|
||||
})
|
||||
console.log(new Array(TERMINAL_SIZE).join("-"))
|
||||
logger.info("Migrations completed")
|
||||
|
||||
/**
|
||||
* Sync links
|
||||
*/
|
||||
if (!skipLinks) {
|
||||
console.log(new Array(TERMINAL_SIZE).join("-"))
|
||||
await syncLinks(medusaAppLoader, {
|
||||
executeAll: executeAllLinks,
|
||||
executeSafe: executeSafeLinks,
|
||||
})
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
const main = async function ({
|
||||
directory,
|
||||
skipLinks,
|
||||
@@ -16,45 +72,13 @@ const main = async function ({
|
||||
executeSafeLinks,
|
||||
}) {
|
||||
try {
|
||||
/**
|
||||
* Setup
|
||||
*/
|
||||
const container = await initializeContainer(directory)
|
||||
await ensureDbExists(container)
|
||||
|
||||
const medusaAppLoader = new MedusaAppLoader()
|
||||
const configModule = container.resolve(
|
||||
ContainerRegistrationKeys.CONFIG_MODULE
|
||||
)
|
||||
|
||||
const plugins = getResolvedPlugins(directory, configModule, true) || []
|
||||
const linksSourcePaths = plugins.map((plugin) =>
|
||||
join(plugin.resolve, "links")
|
||||
)
|
||||
await new LinkLoader(linksSourcePaths).load()
|
||||
|
||||
/**
|
||||
* Run migrations
|
||||
*/
|
||||
logger.info("Running migrations...")
|
||||
await medusaAppLoader.runModulesMigrations({
|
||||
action: "run",
|
||||
const migrated = await migrate({
|
||||
directory,
|
||||
skipLinks,
|
||||
executeAllLinks,
|
||||
executeSafeLinks,
|
||||
})
|
||||
console.log(new Array(TERMINAL_SIZE).join("-"))
|
||||
logger.info("Migrations completed")
|
||||
|
||||
/**
|
||||
* Sync links
|
||||
*/
|
||||
if (!skipLinks) {
|
||||
console.log(new Array(TERMINAL_SIZE).join("-"))
|
||||
await syncLinks(medusaAppLoader, {
|
||||
executeAll: executeAllLinks,
|
||||
executeSafe: executeSafeLinks,
|
||||
})
|
||||
}
|
||||
|
||||
process.exit()
|
||||
process.exit(migrated ? 0 : 1)
|
||||
} catch (error) {
|
||||
logger.error(error)
|
||||
process.exit(1)
|
||||
|
||||
36
packages/medusa/src/commands/db/setup.ts
Normal file
36
packages/medusa/src/commands/db/setup.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { logger } from "@medusajs/framework"
|
||||
import { dbCreate } from "./create"
|
||||
import { migrate } from "./migrate"
|
||||
|
||||
const main = async function ({
|
||||
directory,
|
||||
interactive,
|
||||
db,
|
||||
skipLinks,
|
||||
executeAllLinks,
|
||||
executeSafeLinks,
|
||||
}) {
|
||||
try {
|
||||
const created = await dbCreate({ directory, interactive, db })
|
||||
if (!created) {
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const migrated = await migrate({
|
||||
directory,
|
||||
skipLinks,
|
||||
executeAllLinks,
|
||||
executeSafeLinks,
|
||||
})
|
||||
|
||||
process.exit(migrated ? 0 : 1)
|
||||
} catch (error) {
|
||||
if (error.name === "ExitPromptError") {
|
||||
process.exit()
|
||||
}
|
||||
logger.error(error)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
export default main
|
||||
@@ -193,8 +193,8 @@ const main = async function ({ directory, executeSafe, executeAll }) {
|
||||
|
||||
await syncLinks(medusaAppLoader, { executeAll, executeSafe })
|
||||
process.exit()
|
||||
} catch (e) {
|
||||
logger.error(e)
|
||||
} catch (error) {
|
||||
logger.error(error)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user