feat: CLI + local linking (#313)
* fix: allow local cmd without exiting process * fix: improves cli experience * fix: allow running link with --develop * test: adds snapshot testing of error logs * chore: cleanup * feat(medusa-cli): new command (#320) * adds: new command * fix: creates command for easy project setup * chore: deps * chore: deps * fix: loggin * fix: logging * fix: adds cli as dependency in core * fix: consolidates CLI in medusa * fix: use project deps medusa bin * fix: use project deps medusa bin * fix: use cli path * fix: new command setup db + env vars * fix: new command with db seed * fix: cleanup
This commit is contained in:
@@ -1,10 +1,14 @@
|
||||
const axios = require("axios").default
|
||||
const inquirer = require("inquirer")
|
||||
const open = require("open")
|
||||
const execa = require("execa")
|
||||
const resolveCwd = require(`resolve-cwd`)
|
||||
const { getToken } = require("../util/token-store")
|
||||
const logger = require("../reporter").default
|
||||
|
||||
module.exports = {
|
||||
link: async argv => {
|
||||
const port = process.env.PORT || 9000
|
||||
const appHost =
|
||||
process.env.MEDUSA_APP_HOST || "https://app.medusa-commerce.com"
|
||||
|
||||
@@ -34,7 +38,7 @@ module.exports = {
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
// Get the currenty logged in user; we will be using the Cloud user id to
|
||||
// Get the currently logged in user; we will be using the Cloud user id to
|
||||
// create a user in the local DB with the same user id; allowing you to
|
||||
// authenticate to the local API.
|
||||
const { data: auth } = await axios
|
||||
@@ -48,29 +52,86 @@ module.exports = {
|
||||
process.exit(1)
|
||||
})
|
||||
|
||||
const linkActivity = logger.activity("Linking local project")
|
||||
|
||||
// Create the user with the user id
|
||||
if (!argv.skipLocalUser && auth.user) {
|
||||
const localCmd = resolveLocalCommand(`user`)
|
||||
await localCmd({
|
||||
directory: argv.directory,
|
||||
id: auth.user.id,
|
||||
email: auth.user.email,
|
||||
})
|
||||
let proc
|
||||
try {
|
||||
proc = execa(
|
||||
`./node_modules/@medusajs/medusa/cli.js`,
|
||||
[`user`, `--id`, auth.user.id, `--email`, auth.user.email],
|
||||
{
|
||||
env: {
|
||||
...process.env,
|
||||
NODE_ENV: "command",
|
||||
},
|
||||
}
|
||||
)
|
||||
const res = await proc
|
||||
if (res.stderr) {
|
||||
const err = new Error("stderr error")
|
||||
err.stderr = res.stderr
|
||||
throw err
|
||||
}
|
||||
} catch (error) {
|
||||
logger.failure(linkActivity, "Failed to perform local linking")
|
||||
if (error.stderr) {
|
||||
console.error(error.stderr)
|
||||
} else if (error.code === "ENOENT") {
|
||||
logger.error(
|
||||
`Couldn't find the Medusa CLI - please make sure that you have installed it globally`
|
||||
)
|
||||
}
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// This step sets the Cloud link by opening a browser
|
||||
const bo = await open(
|
||||
`${appHost}/local-link?lurl=http://localhost:9000<oken=${auth.user.id}`,
|
||||
{
|
||||
app: "browser",
|
||||
wait: false,
|
||||
}
|
||||
logger.success(linkActivity, "Local project linked")
|
||||
|
||||
console.log()
|
||||
console.log(
|
||||
"Link Medusa Cloud to your local server. This will open the browser"
|
||||
)
|
||||
bo.on("error", err => {
|
||||
console.warn(err)
|
||||
console.log(
|
||||
`Could not open browser go to: ${appHost}/local-link?lurl=http://localhost:9000<oken=${auth.user.id}`
|
||||
console.log()
|
||||
|
||||
const prompts = [
|
||||
{
|
||||
type: "input",
|
||||
name: "open",
|
||||
message: "Press enter key to open browser for linking or n to exit",
|
||||
},
|
||||
]
|
||||
|
||||
await inquirer.prompt(prompts).then(async a => {
|
||||
if (a.open === "n") {
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
const params = `lurl=http://localhost:${port}<oken=${auth.user.id}`
|
||||
|
||||
// This step sets the Cloud link by opening a browser
|
||||
const browserOpen = await open(
|
||||
`${appHost}/local-link?${encodeURI(params)}`,
|
||||
{
|
||||
app: "browser",
|
||||
wait: false,
|
||||
}
|
||||
)
|
||||
|
||||
browserOpen.on("error", err => {
|
||||
console.warn(err)
|
||||
console.log(
|
||||
`Could not open browser go to: ${appHost}/local-link?lurl=http://localhost:9000<oken=${auth.user.id}`
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
if (argv.develop) {
|
||||
const proc = execa(`./node_modules/@medusajs/medusa/cli.js`, [`develop`])
|
||||
proc.stdout.pipe(process.stdout)
|
||||
proc.stderr.pipe(process.stderr)
|
||||
await proc
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ const axios = require("axios").default
|
||||
const open = require("open")
|
||||
const inquirer = require("inquirer")
|
||||
|
||||
const logger = require("../reporter").default
|
||||
const { setToken } = require("../util/token-store")
|
||||
|
||||
/**
|
||||
@@ -21,7 +22,9 @@ module.exports = {
|
||||
|
||||
const { data: urls } = await axios.post(authHost)
|
||||
|
||||
const qs = [
|
||||
const loginUri = `${loginHost}${urls.browser_url}`
|
||||
|
||||
const prompts = [
|
||||
{
|
||||
type: "input",
|
||||
name: "open",
|
||||
@@ -29,52 +32,58 @@ module.exports = {
|
||||
},
|
||||
]
|
||||
|
||||
await inquirer.prompt(qs).then(async a => {
|
||||
console.log()
|
||||
console.log("Login to Medusa Cloud")
|
||||
console.log()
|
||||
|
||||
await inquirer.prompt(prompts).then(async a => {
|
||||
if (a.open === "n") {
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
const bo = await open(`${loginHost}${urls.browser_url}`, {
|
||||
const browserOpen = await open(loginUri, {
|
||||
app: "browser",
|
||||
wait: false,
|
||||
})
|
||||
bo.on("error", err => {
|
||||
browserOpen.on("error", err => {
|
||||
console.warn(err)
|
||||
console.log(
|
||||
`Could not open browser go to: ${loginHost}${urls.browser_url}`
|
||||
)
|
||||
console.log(`Could not open browser go to: ${loginUri}`)
|
||||
})
|
||||
})
|
||||
|
||||
const spinner = logger.activity(`Waiting for login at ${loginUri}`)
|
||||
const fetchAuth = async (retries = 3) => {
|
||||
try {
|
||||
const { data: auth } = await axios.get(`${authHost}${urls.cli_url}`, {
|
||||
headers: { authorization: `Bearer ${urls.cli_token}` },
|
||||
})
|
||||
return auth
|
||||
} catch (err) {
|
||||
if (retries > 0 && err.http && err.http.statusCode > 500)
|
||||
return fetchAuth(retries - 1)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
const auth = await fetchAuth()
|
||||
|
||||
// This is kept alive for several seconds until the user has authenticated
|
||||
// in the browser.
|
||||
const { data: user } = await axios
|
||||
.get(`${apiHost}/auth`, {
|
||||
headers: {
|
||||
authorization: `Bearer ${auth.password}`,
|
||||
},
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
process.exit(1)
|
||||
})
|
||||
|
||||
const fetchAuth = async (retries = 3) => {
|
||||
try {
|
||||
const { data: auth } = await axios.get(`${authHost}${urls.cli_url}`, {
|
||||
headers: { authorization: `Bearer ${urls.cli_token}` },
|
||||
})
|
||||
return auth
|
||||
} catch (err) {
|
||||
if (retries > 0 && err.http && err.http.statusCode > 500)
|
||||
return fetchAuth(retries - 1)
|
||||
throw err
|
||||
}
|
||||
}
|
||||
const auth = await fetchAuth()
|
||||
|
||||
// This is kept alive for several seconds until the user has authenticated
|
||||
// in the browser.
|
||||
const { data: user } = await axios
|
||||
.get(`${apiHost}/auth`, {
|
||||
headers: {
|
||||
authorization: `Bearer ${auth.password}`,
|
||||
},
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
process.exit(1)
|
||||
})
|
||||
|
||||
if (user) {
|
||||
setToken(auth.password)
|
||||
}
|
||||
})
|
||||
if (user) {
|
||||
logger.success(spinner, "Log in succeeded.")
|
||||
setToken(auth.password)
|
||||
} else {
|
||||
logger.failure(spinner, "Log in failed.")
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
@@ -0,0 +1,450 @@
|
||||
/*
|
||||
* Adapted from https://github.com/gatsbyjs/gatsby/blob/master/packages/gatsby-cli/src/init-starter.ts
|
||||
*/
|
||||
|
||||
import { execSync } from "child_process"
|
||||
import execa from "execa"
|
||||
import { sync as existsSync } from "fs-exists-cached"
|
||||
import fs from "fs-extra"
|
||||
import hostedGitInfo from "hosted-git-info"
|
||||
import isValid from "is-valid-path"
|
||||
import sysPath from "path"
|
||||
import prompts from "prompts"
|
||||
import url from "url"
|
||||
import { createDatabase } from "pg-god"
|
||||
|
||||
import reporter from "../reporter"
|
||||
import { getPackageManager, setPackageManager } from "../util/package-manager"
|
||||
|
||||
const spawnWithArgs = (file, args, options) =>
|
||||
execa(file, args, { stdio: `inherit`, preferLocal: false, ...options })
|
||||
|
||||
const spawn = (cmd, options) => {
|
||||
const [file, ...args] = cmd.split(/\s+/)
|
||||
return spawnWithArgs(file, args, options)
|
||||
}
|
||||
// Checks the existence of yarn package
|
||||
// We use yarnpkg instead of yarn to avoid conflict with Hadoop yarn
|
||||
// Refer to https://github.com/yarnpkg/yarn/issues/673
|
||||
const checkForYarn = () => {
|
||||
try {
|
||||
execSync(`yarnpkg --version`, { stdio: `ignore` })
|
||||
return true
|
||||
} catch (e) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
const isAlreadyGitRepository = async () => {
|
||||
try {
|
||||
return await spawn(`git rev-parse --is-inside-work-tree`, {
|
||||
stdio: `pipe`,
|
||||
}).then(output => output.stdout === `true`)
|
||||
} catch (err) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize newly cloned directory as a git repo
|
||||
const gitInit = async rootPath => {
|
||||
reporter.info(`Initialising git in ${rootPath}`)
|
||||
|
||||
return await spawn(`git init`, { cwd: rootPath })
|
||||
}
|
||||
|
||||
// Create a .gitignore file if it is missing in the new directory
|
||||
const maybeCreateGitIgnore = async rootPath => {
|
||||
if (existsSync(sysPath.join(rootPath, `.gitignore`))) {
|
||||
return
|
||||
}
|
||||
|
||||
const gignore = reporter.activity(
|
||||
`Creating minimal .gitignore in ${rootPath}`
|
||||
)
|
||||
await fs.writeFile(
|
||||
sysPath.join(rootPath, `.gitignore`),
|
||||
`.cache\nnode_modules\npublic\n`
|
||||
)
|
||||
reporter.success(gignore, `Created .gitignore in ${rootPath}`)
|
||||
}
|
||||
|
||||
// Create an initial git commit in the new directory
|
||||
const createInitialGitCommit = async (rootPath, starterUrl) => {
|
||||
reporter.info(`Create initial git commit in ${rootPath}`)
|
||||
|
||||
await spawn(`git add -A`, { cwd: rootPath })
|
||||
// use execSync instead of spawn to handle git clients using
|
||||
// pgp signatures (with password)
|
||||
try {
|
||||
execSync(`git commit -m "Initial commit from gatsby: (${starterUrl})"`, {
|
||||
cwd: rootPath,
|
||||
})
|
||||
} catch {
|
||||
// Remove git support if initial commit fails
|
||||
reporter.warn(`Initial git commit failed - removing git support\n`)
|
||||
fs.removeSync(sysPath.join(rootPath, `.git`))
|
||||
}
|
||||
}
|
||||
|
||||
// Executes `npm install` or `yarn install` in rootPath.
|
||||
const install = async rootPath => {
|
||||
const prevDir = process.cwd()
|
||||
|
||||
reporter.info(`Installing packages...`)
|
||||
process.chdir(rootPath)
|
||||
|
||||
const npmConfigUserAgent = process.env.npm_config_user_agent
|
||||
|
||||
try {
|
||||
if (!getPackageManager()) {
|
||||
if (npmConfigUserAgent?.includes(`yarn`)) {
|
||||
setPackageManager(`yarn`)
|
||||
} else {
|
||||
setPackageManager(`npm`)
|
||||
}
|
||||
}
|
||||
if (getPackageManager() === `yarn` && checkForYarn()) {
|
||||
await fs.remove(`package-lock.json`)
|
||||
await spawn(`yarnpkg`)
|
||||
} else {
|
||||
await fs.remove(`yarn.lock`)
|
||||
await spawn(`npm install`)
|
||||
}
|
||||
} finally {
|
||||
process.chdir(prevDir)
|
||||
}
|
||||
}
|
||||
|
||||
const ignored = path => !/^\.(git|hg)$/.test(sysPath.basename(path))
|
||||
|
||||
// Copy starter from file system.
|
||||
const copy = async (starterPath, rootPath) => {
|
||||
// Chmod with 755.
|
||||
// 493 = parseInt('755', 8)
|
||||
await fs.ensureDir(rootPath, { mode: 493 })
|
||||
|
||||
if (!existsSync(starterPath)) {
|
||||
throw new Error(`starter ${starterPath} doesn't exist`)
|
||||
}
|
||||
|
||||
if (starterPath === `.`) {
|
||||
throw new Error(
|
||||
`You can't create a starter from the existing directory. If you want to
|
||||
create a new project in the current directory, the trailing dot isn't
|
||||
necessary. If you want to create a project from a local starter, run
|
||||
something like "medusa new my-medusa-store ../local-medusa-starter"`
|
||||
)
|
||||
}
|
||||
|
||||
reporter.info(`Creating new site from local starter: ${starterPath}`)
|
||||
|
||||
const copyActivity = reporter.activity(
|
||||
`Copying local starter to ${rootPath} ...`
|
||||
)
|
||||
|
||||
await fs.copy(starterPath, rootPath, { filter: ignored })
|
||||
|
||||
reporter.success(copyActivity, `Created starter directory layout`)
|
||||
|
||||
await install(rootPath)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// Clones starter from URI.
|
||||
const clone = async (hostInfo, rootPath) => {
|
||||
let url
|
||||
// Let people use private repos accessed over SSH.
|
||||
if (hostInfo.getDefaultRepresentation() === `sshurl`) {
|
||||
url = hostInfo.ssh({ noCommittish: true })
|
||||
// Otherwise default to normal git syntax.
|
||||
} else {
|
||||
url = hostInfo.https({ noCommittish: true, noGitPlus: true })
|
||||
}
|
||||
|
||||
const branch = hostInfo.committish ? [`-b`, hostInfo.committish] : []
|
||||
|
||||
const createAct = reporter.activity(`Creating new project from git: ${url}`)
|
||||
|
||||
const args = [
|
||||
`clone`,
|
||||
...branch,
|
||||
url,
|
||||
rootPath,
|
||||
`--recursive`,
|
||||
`--depth=1`,
|
||||
].filter(arg => Boolean(arg))
|
||||
|
||||
await execa(`git`, args, {})
|
||||
.then(() => {
|
||||
reporter.success(createAct, `Created starter directory layout`)
|
||||
})
|
||||
.catch(err => {
|
||||
reporter.failure(createAct, `Failed to clone repository`)
|
||||
throw err
|
||||
})
|
||||
|
||||
await fs.remove(sysPath.join(rootPath, `.git`))
|
||||
|
||||
await install(rootPath)
|
||||
const isGit = await isAlreadyGitRepository()
|
||||
if (!isGit) await gitInit(rootPath)
|
||||
await maybeCreateGitIgnore(rootPath)
|
||||
if (!isGit) await createInitialGitCommit(rootPath, url)
|
||||
}
|
||||
|
||||
const getPaths = async (starterPath, rootPath) => {
|
||||
let selectedOtherStarter = false
|
||||
|
||||
// if no args are passed, prompt user for path and starter
|
||||
if (!starterPath && !rootPath) {
|
||||
const response = await prompts.prompt([
|
||||
{
|
||||
type: `text`,
|
||||
name: `path`,
|
||||
message: `What is your project called?`,
|
||||
initial: `my-medusa-store`,
|
||||
},
|
||||
])
|
||||
// exit gracefully if responses aren't provided
|
||||
if (!response.starter || !response.path.trim()) {
|
||||
throw new Error(
|
||||
`Please mention both starter package and project name along with path(if its not in the root)`
|
||||
)
|
||||
}
|
||||
|
||||
selectedOtherStarter = response.starter === `different`
|
||||
starterPath = `medusajs/medusa-starter-default`
|
||||
rootPath = response.path
|
||||
}
|
||||
|
||||
// set defaults if no root or starter has been set yet
|
||||
rootPath = rootPath || process.cwd()
|
||||
starterPath = starterPath || `medusajs/medusa-starter-default`
|
||||
|
||||
return { starterPath, rootPath, selectedOtherStarter }
|
||||
}
|
||||
|
||||
const successMessage = path => {
|
||||
reporter.info(`
|
||||
Your new Medusa project is ready for you! To start developing run:
|
||||
|
||||
cd ${path}
|
||||
medusa develop
|
||||
`)
|
||||
}
|
||||
|
||||
const defaultDBCreds = {
|
||||
user: "postgres",
|
||||
database: "postgres",
|
||||
password: "",
|
||||
port: 5432,
|
||||
host: "localhost",
|
||||
}
|
||||
|
||||
const setupDB = async (dbName, dbCreds = {}) => {
|
||||
const credentials = Object.assign(defaultDBCreds, dbCreds)
|
||||
|
||||
const dbActivity = reporter.activity(`Setting up database "${dbName}"...`)
|
||||
await createDatabase(
|
||||
{
|
||||
databaseName: dbName,
|
||||
errorIfExist: true,
|
||||
},
|
||||
credentials
|
||||
)
|
||||
.then(() => {
|
||||
reporter.success(dbActivity, `Created database "${dbName}"`)
|
||||
})
|
||||
.catch(err => {
|
||||
if ((err.name = "PDG_ERR::DuplicateDatabase")) {
|
||||
reporter.success(
|
||||
dbActivity,
|
||||
`Database ${dbName} already exists; skipping setup`
|
||||
)
|
||||
} else {
|
||||
reporter.failure(dbActivity, `Skipping database setup.`)
|
||||
reporter.warn(
|
||||
`Failed to setup database; install PostgresQL or make sure to manage your database connection manually`
|
||||
)
|
||||
console.error(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const setupEnvVars = async (rootPath, dbName, dbCreds = {}) => {
|
||||
const credentials = Object.assign(defaultDBCreds, dbCreds)
|
||||
|
||||
const templatePath = sysPath.join(rootPath, ".env.template")
|
||||
const destination = sysPath.join(rootPath, ".env")
|
||||
if (existsSync(templatePath)) {
|
||||
fs.renameSync(templatePath, destination)
|
||||
fs.appendFileSync(
|
||||
destination,
|
||||
`DATABASE_URL=postgres://${credentials.user}:${credentials.password}@${credentials.host}:${credentials.port}/${dbName}\n`
|
||||
)
|
||||
} else {
|
||||
reporter.info(`No .env.template found. Creating .env.`)
|
||||
fs.appendFileSync(
|
||||
destination,
|
||||
`DATABASE_URL=postgres://${credentials.user}:${credentials.password}@${credentials.host}:${credentials.port}/${dbName}\n`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const runMigrations = async rootPath => {
|
||||
const migrationActivity = reporter.activity("Applying database migrations...")
|
||||
|
||||
const cliPath = sysPath.join(
|
||||
`node_modules`,
|
||||
`@medusajs`,
|
||||
`medusa-cli`,
|
||||
`cli.js`
|
||||
)
|
||||
|
||||
return await execa(cliPath, [`migrations`, `run`], {
|
||||
cwd: rootPath,
|
||||
})
|
||||
.then(() => {
|
||||
reporter.success(migrationActivity, "Database migrations completed.")
|
||||
})
|
||||
.catch(err => {
|
||||
reporter.failure(
|
||||
migrationActivity,
|
||||
"Failed to migrate database you must complete migration manually before starting your server."
|
||||
)
|
||||
console.error(err)
|
||||
})
|
||||
}
|
||||
|
||||
const attemptSeed = async rootPath => {
|
||||
const seedActivity = reporter.activity("Seeding database")
|
||||
|
||||
const pkgPath = sysPath.resolve(rootPath, "package.json")
|
||||
if (existsSync(pkgPath)) {
|
||||
const pkg = require(pkgPath)
|
||||
if (pkg.scripts && pkg.scripts.seed) {
|
||||
const proc = execa(getPackageManager(), [`run`, `seed`], {
|
||||
cwd: rootPath,
|
||||
})
|
||||
|
||||
// Useful for development
|
||||
// proc.stdout.pipe(process.stdout)
|
||||
|
||||
await proc
|
||||
.then(() => {
|
||||
reporter.success(seedActivity, "Seed completed")
|
||||
})
|
||||
.catch(err => {
|
||||
reporter.failure(seedActivity, "Failed to complete seed; skipping")
|
||||
console.error(err)
|
||||
})
|
||||
} else {
|
||||
reporter.failure(
|
||||
seedActivity,
|
||||
"Starter doesn't provide a seed command; skipping."
|
||||
)
|
||||
}
|
||||
} else {
|
||||
reporter.failure(seedActivity, "Could not find package.json")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Main function that clones or copies the starter.
|
||||
*/
|
||||
export const newStarter = async args => {
|
||||
const {
|
||||
starter,
|
||||
root,
|
||||
skipDb,
|
||||
skipMigrations,
|
||||
skipEnv,
|
||||
seed,
|
||||
dbUser,
|
||||
dbDatabase,
|
||||
dbPass,
|
||||
dbPort,
|
||||
dbHost,
|
||||
} = args
|
||||
|
||||
const dbCredentials = {
|
||||
user: dbUser,
|
||||
database: dbDatabase,
|
||||
password: dbPass,
|
||||
port: dbPort,
|
||||
host: dbHost,
|
||||
}
|
||||
|
||||
const { starterPath, rootPath } = await getPaths(starter, root)
|
||||
|
||||
const urlObject = url.parse(rootPath)
|
||||
|
||||
if (urlObject.protocol && urlObject.host) {
|
||||
const isStarterAUrl =
|
||||
starter && !url.parse(starter).hostname && !url.parse(starter).protocol
|
||||
|
||||
if (/medusa-starter/gi.test(rootPath) && isStarterAUrl) {
|
||||
reporter.panic({
|
||||
id: `11610`,
|
||||
context: {
|
||||
starter,
|
||||
rootPath,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
reporter.panic({
|
||||
id: `11611`,
|
||||
context: {
|
||||
rootPath,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if (!isValid(rootPath)) {
|
||||
reporter.panic({
|
||||
id: `11612`,
|
||||
context: {
|
||||
path: sysPath.resolve(rootPath),
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if (existsSync(sysPath.join(rootPath, `package.json`))) {
|
||||
reporter.panic({
|
||||
id: `11613`,
|
||||
context: {
|
||||
rootPath,
|
||||
},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
const hostedInfo = hostedGitInfo.fromUrl(starterPath)
|
||||
if (hostedInfo) {
|
||||
await clone(hostedInfo, rootPath)
|
||||
} else {
|
||||
await copy(starterPath, rootPath)
|
||||
}
|
||||
|
||||
if (!skipDb) {
|
||||
await setupDB(root, dbCredentials)
|
||||
}
|
||||
|
||||
if (!skipEnv) {
|
||||
await setupEnvVars(rootPath, root, dbCredentials)
|
||||
}
|
||||
|
||||
if (!skipMigrations) {
|
||||
await runMigrations(rootPath)
|
||||
}
|
||||
|
||||
if (seed) {
|
||||
await attemptSeed(rootPath)
|
||||
}
|
||||
|
||||
successMessage(rootPath)
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
const axios = require("axios").default
|
||||
const { getToken } = require("../util/token-store")
|
||||
const logger = require("../reporter").default
|
||||
|
||||
/**
|
||||
* Fetches the locally logged in user.
|
||||
@@ -18,6 +19,8 @@ module.exports = {
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
const activity = logger.activity("checking login details")
|
||||
|
||||
const { data: auth } = await axios
|
||||
.get(`${apiHost}/auth`, {
|
||||
headers: {
|
||||
@@ -25,12 +28,17 @@ module.exports = {
|
||||
},
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
logger.failure(activity, "Couldn't gather login details")
|
||||
logger.error(err)
|
||||
process.exit(1)
|
||||
})
|
||||
|
||||
if (auth.user) {
|
||||
console.log(`Hi, ${auth.user.first_name}! Here are your details:`)
|
||||
logger.success(
|
||||
activity,
|
||||
`Hi, ${auth.user.first_name}! Here are your details:`
|
||||
)
|
||||
|
||||
console.log(`id: ${auth.user.id}`)
|
||||
console.log(`email: ${auth.user.email}`)
|
||||
console.log(`first_name: ${auth.user.first_name}`)
|
||||
|
||||
Reference in New Issue
Block a user