feature: add db:setup command (#8830)
This commit is contained in:
1 parent
841cb69ba9
commit
69c5d122b1
5 files changed
+171
-58
No files matched your search
@@ -120,6 +120,42 @@ function buildLocalCommands(cli, isLocalProject) {
|
|||||||
desc: `Create a new Medusa project.`,
|
desc: `Create a new Medusa project.`,
|
||||||
handler: handlerP(newStarter),
|
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({
|
||||||
command: "db:create",
|
command: "db:create",
|
||||||
desc: "Create the database used by your application",
|
desc: "Create the database used by your application",
|
||||||
|
|||||||
@@ -10,7 +10,19 @@ import {
|
|||||||
parseConnectionString,
|
parseConnectionString,
|
||||||
} from "@medusajs/utils"
|
} 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
|
let dbName = db
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -33,8 +45,7 @@ const main = async function ({ directory, interactive, db }) {
|
|||||||
logger.error(
|
logger.error(
|
||||||
`Missing "DATABASE_URL" inside the .env file. The value is required to connect to the PostgreSQL server`
|
`Missing "DATABASE_URL" inside the .env file. The value is required to connect to the PostgreSQL server`
|
||||||
)
|
)
|
||||||
process.exitCode = 1
|
return false
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -45,18 +56,11 @@ const main = async function ({ directory, interactive, db }) {
|
|||||||
const defaultValue =
|
const defaultValue =
|
||||||
envEditor.get("DB_NAME") ?? `medusa-${slugify(basename(directory))}`
|
envEditor.get("DB_NAME") ?? `medusa-${slugify(basename(directory))}`
|
||||||
if (interactive) {
|
if (interactive) {
|
||||||
try {
|
dbName = await input({
|
||||||
dbName = await input({
|
message: "Enter the database name",
|
||||||
message: "Enter the database name",
|
default: defaultValue,
|
||||||
default: defaultValue,
|
required: true,
|
||||||
required: true,
|
})
|
||||||
})
|
|
||||||
} catch (error) {
|
|
||||||
if (error.name === "ExitPromptError") {
|
|
||||||
process.exit()
|
|
||||||
}
|
|
||||||
throw error
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
dbName = defaultValue
|
dbName = defaultValue
|
||||||
}
|
}
|
||||||
@@ -82,12 +86,11 @@ const main = async function ({ directory, interactive, db }) {
|
|||||||
await client.connect()
|
await client.connect()
|
||||||
logger.info(`Connection established with the database "${dbName}"`)
|
logger.info(`Connection established with the database "${dbName}"`)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
process.exitCode = 1
|
|
||||||
logger.error(
|
logger.error(
|
||||||
"Unable to establish database connection because of the following error"
|
"Unable to establish database connection because of the following error"
|
||||||
)
|
)
|
||||||
logger.error(error)
|
logger.error(error)
|
||||||
return
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (await dbExists(client, dbName)) {
|
if (await dbExists(client, dbName)) {
|
||||||
@@ -97,7 +100,7 @@ const main = async function ({ directory, interactive, db }) {
|
|||||||
await envEditor.save()
|
await envEditor.save()
|
||||||
logger.info(`Updated .env file with "DB_NAME=${dbName}"`)
|
logger.info(`Updated .env file with "DB_NAME=${dbName}"`)
|
||||||
|
|
||||||
return
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
await createDb(client, dbName)
|
await createDb(client, dbName)
|
||||||
@@ -106,6 +109,20 @@ const main = async function ({ directory, interactive, db }) {
|
|||||||
envEditor.set("DB_NAME", dbName)
|
envEditor.set("DB_NAME", dbName)
|
||||||
await envEditor.save()
|
await envEditor.save()
|
||||||
logger.info(`Updated .env file with "DB_NAME=${dbName}"`)
|
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
|
export default main
|
||||||
@@ -9,6 +9,62 @@ import { getResolvedPlugins } from "../../loaders/helpers/resolve-plugins"
|
|||||||
|
|
||||||
const TERMINAL_SIZE = process.stdout.columns
|
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 ({
|
const main = async function ({
|
||||||
directory,
|
directory,
|
||||||
skipLinks,
|
skipLinks,
|
||||||
@@ -16,45 +72,13 @@ const main = async function ({
|
|||||||
executeSafeLinks,
|
executeSafeLinks,
|
||||||
}) {
|
}) {
|
||||||
try {
|
try {
|
||||||
/**
|
const migrated = await migrate({
|
||||||
* Setup
|
directory,
|
||||||
*/
|
skipLinks,
|
||||||
const container = await initializeContainer(directory)
|
executeAllLinks,
|
||||||
await ensureDbExists(container)
|
executeSafeLinks,
|
||||||
|
|
||||||
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("-"))
|
process.exit(migrated ? 0 : 1)
|
||||||
logger.info("Migrations completed")
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sync links
|
|
||||||
*/
|
|
||||||
if (!skipLinks) {
|
|
||||||
console.log(new Array(TERMINAL_SIZE).join("-"))
|
|
||||||
await syncLinks(medusaAppLoader, {
|
|
||||||
executeAll: executeAllLinks,
|
|
||||||
executeSafe: executeSafeLinks,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
process.exit()
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(error)
|
logger.error(error)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
|
|||||||
@@ -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 })
|
await syncLinks(medusaAppLoader, { executeAll, executeSafe })
|
||||||
process.exit()
|
process.exit()
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
logger.error(e)
|
logger.error(error)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user