diff --git a/.changeset/late-dragons-collect.md b/.changeset/late-dragons-collect.md new file mode 100644 index 0000000000..8ae2382de9 --- /dev/null +++ b/.changeset/late-dragons-collect.md @@ -0,0 +1,12 @@ +--- +"@medusajs/medusa": patch +"@medusajs/event-bus-local": patch +"@medusajs/event-bus-redis": patch +"@medusajs/medusa-cli": patch +"medusa-plugin-algolia": patch +"medusa-plugin-meilisearch": patch +"@medusajs/product": patch +"@medusajs/types": patch +--- + +chore(medusa-cli): Cleanup plugin setup + include Logger type update which is used across multiple packages diff --git a/packages/event-bus-local/src/services/event-bus-local.ts b/packages/event-bus-local/src/services/event-bus-local.ts index 2acd56f7f5..e45b3a57a2 100644 --- a/packages/event-bus-local/src/services/event-bus-local.ts +++ b/packages/event-bus-local/src/services/event-bus-local.ts @@ -1,5 +1,5 @@ -import { Logger, MedusaContainer } from "@medusajs/modules-sdk" -import { EmitData, EventBusTypes, Subscriber } from "@medusajs/types" +import { MedusaContainer } from "@medusajs/modules-sdk" +import { EmitData, EventBusTypes, Logger, Subscriber } from "@medusajs/types" import { AbstractEventBusModuleService } from "@medusajs/utils" import { EventEmitter } from "events" import { ulid } from "ulid" diff --git a/packages/event-bus-redis/src/services/event-bus-redis.ts b/packages/event-bus-redis/src/services/event-bus-redis.ts index ba318988d0..5271237947 100644 --- a/packages/event-bus-redis/src/services/event-bus-redis.ts +++ b/packages/event-bus-redis/src/services/event-bus-redis.ts @@ -1,5 +1,5 @@ -import { InternalModuleDeclaration, Logger } from "@medusajs/modules-sdk" -import { EmitData } from "@medusajs/types" +import { InternalModuleDeclaration } from "@medusajs/modules-sdk" +import { EmitData, Logger } from "@medusajs/types" import { AbstractEventBusModuleService } from "@medusajs/utils" import { BulkJobOptions, JobsOptions, Queue, Worker } from "bullmq" import { Redis } from "ioredis" diff --git a/packages/medusa-cli/.babelrc b/packages/medusa-cli/.babelrc deleted file mode 100644 index b48db12268..0000000000 --- a/packages/medusa-cli/.babelrc +++ /dev/null @@ -1,9 +0,0 @@ -{ - "plugins": ["@babel/plugin-proposal-class-properties"], - "presets": ["@babel/preset-env"], - "env": { - "test": { - "plugins": ["@babel/plugin-transform-runtime"] - } - } -} diff --git a/packages/medusa-cli/jest.config.js b/packages/medusa-cli/jest.config.js new file mode 100644 index 0000000000..14cd7ed6e7 --- /dev/null +++ b/packages/medusa-cli/jest.config.js @@ -0,0 +1,13 @@ +module.exports = { + globals: { + "ts-jest": { + tsConfig: "tsconfig.spec.json", + isolatedModules: false, + }, + }, + transform: { + "^.+\\.[jt]s?$": "ts-jest", + }, + testEnvironment: `node`, + moduleFileExtensions: [`js`, `jsx`, `ts`, `tsx`, `json`], +} diff --git a/packages/medusa-cli/package.json b/packages/medusa-cli/package.json index 164f00cd0b..04dec2b71b 100644 --- a/packages/medusa-cli/package.json +++ b/packages/medusa-cli/package.json @@ -20,20 +20,18 @@ ], "scripts": { "test": "jest --passWithNoTests src", - "build": "babel src --out-dir dist/ --ignore '**/__tests__','**/__mocks__'", - "watch": "babel -w src --out-dir dist/ --ignore '**/__tests__','**/__mocks__'", + "build": "tsc", + "watch": "tsc --watch", "prepare": "cross-env NODE_ENV=production yarn run build" }, "author": "Sebastian Rindom", "license": "MIT", "devDependencies": { - "@babel/cli": "^7.7.5", - "@babel/core": "^7.7.5", - "@babel/plugin-proposal-class-properties": "^7.7.4", - "@babel/plugin-transform-runtime": "^7.7.6", - "@babel/preset-env": "^7.7.5", + "@types/yargs": "^15.0.15", "cross-env": "^5.2.1", - "jest": "^25.5.4" + "jest": "^25.5.4", + "ts-jest": "^25.5.1", + "typescript": "^4.9.5" }, "dependencies": { "@medusajs/utils": "^1.9.1", @@ -61,7 +59,6 @@ "semver": "^7.3.8", "stack-trace": "^0.0.10", "ulid": "^2.3.0", - "url": "^0.11.0", "winston": "^3.8.2", "yargs": "^15.3.1" }, diff --git a/packages/medusa-cli/src/commands/link.js b/packages/medusa-cli/src/commands/link.js deleted file mode 100644 index 1d45220d2e..0000000000 --- a/packages/medusa-cli/src/commands/link.js +++ /dev/null @@ -1,139 +0,0 @@ -const axios = require("axios").default -const inquirer = require("inquirer") -const open = require("open") -const execa = require("execa") -const resolveCwd = require(`resolve-cwd`) -const { track } = require("medusa-telemetry") - -const { getToken } = require("../util/token-store") -const logger = require("../reporter").default - -const MEDUSA_CLI_DEBUG = process.env.MEDUSA_CLI_DEBUG || false - -module.exports = { - link: async argv => { - track("CLI_LINK", { args: argv }) - const port = process.env.PORT || 9000 - const appHost = - process.env.MEDUSA_APP_HOST || "https://app.medusa-commerce.com" - - const apiHost = - process.env.MEDUSA_API_HOST || "https://api.medusa-commerce.com" - - // Checks if there is already a token from a previous log in; this is - // necessary to redirect the customer to the page where local linking is - // done - const tok = getToken() - if (!tok) { - console.log( - "You must login to Medusa Cloud first. Please run medusa login." - ) - process.exit(1) - } - - // 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 - .get(`${apiHost}/auth`, { - headers: { - authorization: `Bearer ${tok}`, - }, - }) - .catch(err => { - console.log(err) - process.exit(1) - }) - - const linkActivity = logger.activity("Linking local project") - - // Create the user with the user id - if (!argv.skipLocalUser && auth.user) { - 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", - }, - } - ) - - if (MEDUSA_CLI_DEBUG) { - proc.stderr.pipe(process.stderr) - proc.stdout.pipe(process.stdout) - } - - 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) - } - } - - logger.success(linkActivity, "Local project linked") - track("CLI_LINK_COMPLETED") - - console.log() - console.log( - "Link Medusa Cloud to your local server. This will open the browser" - ) - 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}` - ) - }) - - track("CLI_LINK_BROWSER_OPENED") - }) - - 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 - } - }, -} diff --git a/packages/medusa-cli/src/commands/login.js b/packages/medusa-cli/src/commands/login.js deleted file mode 100644 index d5890e0ecf..0000000000 --- a/packages/medusa-cli/src/commands/login.js +++ /dev/null @@ -1,93 +0,0 @@ -const axios = require("axios").default -const open = require("open") -const inquirer = require("inquirer") -const { track } = require("medusa-telemetry") - -const logger = require("../reporter").default -const { setToken } = require("../util/token-store") - -/** - * The login command allows the CLI to keep track of Cloud users; the command - * makes a cli-login request to the cloud server and keeps an open connection - * until the user has authenticated via the Medusa Cloud website. - */ -module.exports = { - login: async _ => { - track("CLI_LOGIN") - const apiHost = - process.env.MEDUSA_API_HOST || "https://api.medusa-commerce.com" - - const authHost = process.env.MEDUSA_AUTH_HOST || `${apiHost}/cli-auth` - - const loginHost = - process.env.MEDUSA_APP_HOST || "https://app.medusa-commerce.com" - - const { data: urls } = await axios.post(authHost) - - const loginUri = `${loginHost}${urls.browser_url}` - - const prompts = [ - { - type: "input", - name: "open", - message: "Press enter key to open browser for login or n to exit", - }, - ] - - 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 browserOpen = await open(loginUri, { - app: "browser", - wait: false, - }) - browserOpen.on("error", err => { - console.warn(err) - 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) - }) - - if (user) { - track("CLI_LOGIN_SUCCEEDED") - logger.success(spinner, "Log in succeeded.") - setToken(auth.password) - } else { - track("CLI_LOGIN_FAILED") - logger.failure(spinner, "Log in failed.") - } - }, -} diff --git a/packages/medusa-cli/src/commands/new.js b/packages/medusa-cli/src/commands/new.ts similarity index 97% rename from packages/medusa-cli/src/commands/new.js rename to packages/medusa-cli/src/commands/new.ts index df6cfccebd..e54f88e10f 100644 --- a/packages/medusa-cli/src/commands/new.js +++ b/packages/medusa-cli/src/commands/new.ts @@ -19,12 +19,13 @@ import inquirer from "inquirer" import reporter from "../reporter" import { getPackageManager, setPackageManager } from "../util/package-manager" import { clearProject } from "@medusajs/utils" +import { PanicId } from "../reporter/panic-handler" const removeUndefined = (obj) => { return Object.fromEntries( Object.entries(obj) .filter(([_, v]) => v != null) - .map(([k, v]) => [k, v === Object(v) ? removeEmpty(v) : v]) + .map(([k, v]) => [k, v === Object(v) ? removeUndefined(v) : v]) ) } @@ -119,10 +120,10 @@ const install = async (rootPath) => { } if (getPackageManager() === `yarn` && checkForYarn()) { await fs.remove(`package-lock.json`) - await spawn(`yarnpkg`) + await spawn(`yarnpkg`, {}) } else { await fs.remove(`yarn.lock`) - await spawn(`npm install`) + await spawn(`npm install`, {}) } } finally { process.chdir(prevDir) @@ -389,6 +390,8 @@ Do you wish to continue with these credentials? console.log("\n\nCould not verify DB credentials - please try again\n\n") } + + return } const setupDB = async (dbName, dbCreds = {}) => { @@ -553,7 +556,7 @@ medusa new ${rootPath} [url-to-starter] if (/medusa-starter/gi.test(rootPath) && isStarterAUrl) { reporter.panic({ - id: `10000`, + id: PanicId.InvalidProjectName, context: { starter, rootPath, @@ -561,8 +564,9 @@ medusa new ${rootPath} [url-to-starter] }) return } + reporter.panic({ - id: `10001`, + id: PanicId.InvalidProjectName, context: { rootPath, }, @@ -572,7 +576,7 @@ medusa new ${rootPath} [url-to-starter] if (!isValid(rootPath)) { reporter.panic({ - id: `10002`, + id: PanicId.InvalidPath, context: { path: sysPath.resolve(rootPath), }, @@ -582,7 +586,7 @@ medusa new ${rootPath} [url-to-starter] if (existsSync(sysPath.join(rootPath, `package.json`))) { reporter.panic({ - id: `10003`, + id: PanicId.AlreadyNodeProject, context: { rootPath, }, diff --git a/packages/medusa-cli/src/commands/whoami.js b/packages/medusa-cli/src/commands/whoami.js deleted file mode 100644 index 54d25059bd..0000000000 --- a/packages/medusa-cli/src/commands/whoami.js +++ /dev/null @@ -1,48 +0,0 @@ -const axios = require("axios").default -const { getToken } = require("../util/token-store") -const logger = require("../reporter").default - -/** - * Fetches the locally logged in user. - */ -module.exports = { - whoami: async argv => { - const apiHost = - process.env.MEDUSA_API_HOST || "https://api.medusa-commerce.com" - - const tok = getToken() - - if (!tok) { - console.log( - "You are not logged into Medusa Cloud. Please run medusa login." - ) - process.exit(0) - } - - const activity = logger.activity("checking login details") - - const { data: auth } = await axios - .get(`${apiHost}/auth`, { - headers: { - authorization: `Bearer ${tok}`, - }, - }) - .catch(err => { - logger.failure(activity, "Couldn't gather login details") - logger.error(err) - process.exit(1) - }) - - if (auth.user) { - 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}`) - console.log(`last_name: ${auth.user.last_name}`) - } - }, -} diff --git a/packages/medusa-cli/src/create-cli.js b/packages/medusa-cli/src/create-cli.ts similarity index 83% rename from packages/medusa-cli/src/create-cli.js rename to packages/medusa-cli/src/create-cli.ts index a124004f51..3b1e9ceae3 100644 --- a/packages/medusa-cli/src/create-cli.js +++ b/packages/medusa-cli/src/create-cli.ts @@ -1,17 +1,15 @@ -const path = require(`path`) -const resolveCwd = require(`resolve-cwd`) +import path from "path" +import resolveCwd from "resolve-cwd" +import { sync as existsSync } from "fs-exists-cached" +import { setTelemetryEnabled } from "medusa-telemetry" + +import { getLocalMedusaVersion } from "./util/version" +import { didYouMean } from "./did-you-mean" + +import reporter from "./reporter" +import { newStarter } from "./commands/new" + const yargs = require(`yargs`) -const existsSync = require(`fs-exists-cached`).sync -const { setTelemetryEnabled } = require("medusa-telemetry") - -const { getLocalMedusaVersion } = require(`./util/version`) -const { didYouMean } = require(`./did-you-mean`) - -const reporter = require("./reporter").default -const { newStarter } = require("./commands/new") -const { whoami } = require("./commands/whoami") -const { login } = require("./commands/login") -const { link } = require("./commands/link") const handlerP = (fn) => @@ -31,18 +29,10 @@ function buildLocalCommands(cli, isLocalProject) { const useYarn = existsSync(path.join(directory, `yarn.lock`)) if (isLocalProject) { - const json = require(path.join(directory, `package.json`)) - projectInfo.sitePackageJson = json - } - - function getLocalMedusaMajorVersion() { - let version = getLocalMedusaVersion() - - if (version) { - version = Number(version.split(`.`)[0]) - } - - return version + projectInfo["sitePackageJson"] = require(path.join( + directory, + `package.json` + )) } function resolveLocalCommand(command) { @@ -53,10 +43,10 @@ function buildLocalCommands(cli, isLocalProject) { try { const cmdPath = resolveCwd.silent( `@medusajs/medusa/dist/commands/${command}` - ) + )! return require(cmdPath).default } catch (err) { - if (process.env.NODE_ENV !== "production") { + if (!process.env.NODE_ENV?.startsWith("prod")) { console.log("--------------- ERROR ---------------------") console.log(err) console.log("-------------------------------------------") @@ -166,7 +156,7 @@ function buildLocalCommands(cli, isLocalProject) { }), handler: handlerP( getCommandHandler(`seed`, (args, cmd) => { - process.env.NODE_ENV = process.env.NODE_ENV || `development` + process.env.NODE_ENV ??= `development` return cmd(args) }) ), @@ -187,41 +177,6 @@ function buildLocalCommands(cli, isLocalProject) { }) ), }) - .command({ - command: `whoami`, - desc: `View the details of the currently logged in user.`, - handler: handlerP(whoami), - }) - .command({ - command: `link`, - desc: `Creates your Medusa Cloud user in your local database for local testing.`, - builder: (_) => - _.option(`su`, { - alias: `skip-local-user`, - type: `boolean`, - default: false, - describe: `If set a user will not be created in the database.`, - }).option(`develop`, { - type: `boolean`, - default: false, - describe: `If set medusa develop will be run after successful linking.`, - }), - handler: handlerP((argv) => { - if (!isLocalProject) { - console.log("must be a local project") - cli.showHelp() - } - - const args = { ...argv, ...projectInfo, useYarn } - - return link(args) - }), - }) - .command({ - command: `login`, - desc: `Logs you into Medusa Cloud.`, - handler: handlerP(login), - }) .command({ command: `develop`, desc: `Start development server. Watches file and rebuilds when something changes`, @@ -316,17 +271,20 @@ function buildLocalCommands(cli, isLocalProject) { function isLocalMedusaProject() { let inMedusaProject = false + try { const { dependencies, devDependencies } = require(path.resolve( `./package.json` )) - inMedusaProject = + inMedusaProject = !!( (dependencies && dependencies["@medusajs/medusa"]) || (devDependencies && devDependencies["@medusajs/medusa"]) + ) } catch (err) { - /* ignore */ + // ignore } - return !!inMedusaProject + + return inMedusaProject } function getVersionInfo() { @@ -347,7 +305,7 @@ Medusa version: ${medusaVersion} } } -module.exports = (argv) => { +export default (argv) => { const cli = yargs() const isLocalProject = isLocalMedusaProject() @@ -402,7 +360,7 @@ module.exports = (argv) => { const arg = argv.slice(2)[0] const suggestion = arg ? didYouMean(arg, availableCommands) : `` - if (process.env.NODE_ENV !== "production") { + if (!process.env.NODE_ENV?.startsWith("prod")) { console.log("--------------- ERROR ---------------------") console.log(err) console.log("-------------------------------------------") diff --git a/packages/medusa-cli/src/did-you-mean.js b/packages/medusa-cli/src/did-you-mean.ts similarity index 74% rename from packages/medusa-cli/src/did-you-mean.js rename to packages/medusa-cli/src/did-you-mean.ts index a818bdb46b..70011d5d40 100644 --- a/packages/medusa-cli/src/did-you-mean.js +++ b/packages/medusa-cli/src/did-you-mean.ts @@ -1,7 +1,7 @@ import meant from "meant" -export function didYouMean(scmd, commands) { - const bestSimilarity = meant(scmd, commands).map(str => { +export function didYouMean(scmd, commands): string { + const bestSimilarity = meant(scmd, commands).map((str) => { return ` ${str}` }) diff --git a/packages/medusa-cli/src/index.js b/packages/medusa-cli/src/index.js deleted file mode 100644 index 998df3496e..0000000000 --- a/packages/medusa-cli/src/index.js +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/env node - -import "core-js/stable" -import "regenerator-runtime/runtime" -import os from "os" -import semver from "semver" -import util from "util" -import createCli from "./create-cli" -// import report from "./reporter" -import pkg from "../package.json" -// import updateNotifier from "update-notifier" -// import { ensureWindowsDriveLetterIsUppercase } from "./util/ensure-windows-drive-letter-is-uppercase" - -const useJsonLogger = process.argv.slice(2).some(arg => arg.includes(`json`)) - -if (useJsonLogger) { - process.env.GATSBY_LOGGER = `json` -} - -// Ensure stable runs on Windows when started from different shells (i.e. c:\dir vs C:\dir) -if (os.platform() === `win32`) { - // ensureWindowsDriveLetterIsUppercase() -} - -// Check if update is available -// updateNotifier({ pkg }).notify({ isGlobal: true }) - -const MIN_NODE_VERSION = `10.13.0` -// const NEXT_MIN_NODE_VERSION = `10.13.0` - -if (!semver.satisfies(process.version, `>=${MIN_NODE_VERSION}`)) { - //report.panic( - // report.stripIndent(` - // Gatsby requires Node.js ${MIN_NODE_VERSION} or higher (you have ${process.version}). - // Upgrade Node to the latest stable release: https://gatsby.dev/upgrading-node-js - // `) - //) -} - -// if (!semver.satisfies(process.version, `>=${NEXT_MIN_NODE_VERSION}`)) { -// report.warn( -// report.stripIndent(` -// Node.js ${process.version} has reached End of Life status on 31 December, 2019. -// Gatsby will only actively support ${NEXT_MIN_NODE_VERSION} or higher and drop support for Node 8 soon. -// Please upgrade Node.js to a currently active LTS release: https://gatsby.dev/upgrading-node-js -// `) -// ) -// } - -process.on(`unhandledRejection`, reason => { - // This will exit the process in newer Node anyway so lets be consistent - // across versions and crash - - // reason can be anything, it can be a message, an object, ANYTHING! - // we convert it to an error object so we don't crash on structured error validation - if (!(reason instanceof Error)) { - reason = new Error(util.format(reason)) - } - - console.log(reason) - // report.panic(`UNHANDLED REJECTION`, reason as Error) -}) - -process.on(`uncaughtException`, error => { - console.log(error) - // report.panic(`UNHANDLED EXCEPTION`, error) -}) - -createCli(process.argv) diff --git a/packages/medusa-cli/src/index.ts b/packages/medusa-cli/src/index.ts new file mode 100644 index 0000000000..d7ee720500 --- /dev/null +++ b/packages/medusa-cli/src/index.ts @@ -0,0 +1,44 @@ +#!/usr/bin/env node + +import "core-js/stable" +import "regenerator-runtime/runtime" +import os from "os" +import util from "util" +import createCli from "./create-cli" + +const useJsonLogger = process.argv.slice(2).some((arg) => arg.includes(`json`)) + +if (useJsonLogger) { + process.env.GATSBY_LOGGER = `json` +} + +// Ensure stable runs on Windows when started from different shells (i.e. c:\dir vs C:\dir) +if (os.platform() === `win32`) { + // ensureWindowsDriveLetterIsUppercase() +} + +// Check if update is available +// updateNotifier({ pkg }).notify({ isGlobal: true }) + +const MIN_NODE_VERSION = `10.13.0` + +process.on(`unhandledRejection`, (reason) => { + // This will exit the process in newer Node anyway so lets be consistent + // across versions and crash + + // reason can be anything, it can be a message, an object, ANYTHING! + // we convert it to an error object, so we don't crash on structured error validation + if (!(reason instanceof Error)) { + reason = new Error(util.format(reason)) + } + + console.log(reason) + // report.panic(`UNHANDLED REJECTION`, reason as Error) +}) + +process.on(`uncaughtException`, (error) => { + console.log(error) + // report.panic(`UNHANDLED EXCEPTION`, error) +}) + +createCli(process.argv) diff --git a/packages/medusa-cli/src/reporter/index.js b/packages/medusa-cli/src/reporter/index.ts similarity index 91% rename from packages/medusa-cli/src/reporter/index.js rename to packages/medusa-cli/src/reporter/index.ts index db87c6b4f9..7ed1bd2e3c 100644 --- a/packages/medusa-cli/src/reporter/index.js +++ b/packages/medusa-cli/src/reporter/index.ts @@ -5,12 +5,14 @@ import ora from "ora" import { track } from "medusa-telemetry" import { panicHandler } from "./panic-handler" +import * as Transport from "winston-transport" const LOG_LEVEL = process.env.LOG_LEVEL || "silly" const NODE_ENV = process.env.NODE_ENV || "development" -const IS_DEV = NODE_ENV === "development" +const IS_DEV = NODE_ENV.startsWith("dev") + +let transports: Transport[] = [] -const transports = [] if (!IS_DEV) { transports.push(new winston.transports.Console()) } else { @@ -39,8 +41,12 @@ const loggerInstance = winston.createLogger({ }) export class Reporter { + protected activities_: Record + protected loggerInstance_: winston.Logger + protected ora_: typeof ora + constructor({ logger, activityLogger }) { - this.activities_ = [] + this.activities_ = {} this.loggerInstance_ = logger this.ora_ = activityLogger } @@ -92,6 +98,7 @@ export class Reporter { * Begin an activity. In development an activity is displayed as a spinner; * in other environments it will log the activity at the info level. * @param {string} message - the message to log the activity under + * @param {any} config * @returns {string} the id of the activity; this should be passed to do * further operations on the activity such as success, failure, progress. */ @@ -141,7 +148,7 @@ export class Reporter { if (activity.activity) { activity.text = message } else { - toLog.activity_id = activityId + toLog["activity_id"] = activityId this.loggerInstance_.log(toLog) } } else { @@ -156,7 +163,7 @@ export class Reporter { * message to log the error under; or an error object. * @param {Error?} error - an error object to log message with */ - error = (messageOrError, error) => { + error = (messageOrError, error = null) => { let message = messageOrError if (typeof messageOrError === "object") { message = messageOrError.message @@ -169,7 +176,7 @@ export class Reporter { } if (error) { - toLog.stack = stackTrace.parse(error) + toLog["stack"] = stackTrace.parse(error) } this.loggerInstance_.log(toLog) @@ -200,8 +207,8 @@ export class Reporter { if (activity.activity) { activity.activity.fail(`${message} – ${time - activity.start}`) } else { - toLog.duration = time - activity.start - toLog.activity_id = activityId + toLog["duration"] = time - activity.start + toLog["activity_id"] = activityId this.loggerInstance_.log(toLog) } } else { @@ -225,7 +232,7 @@ export class Reporter { * at the info level. * @param {string} activityId - the id of the activity as returned by activity * @param {string} message - the message to log - * @returns {object} data about the activity + * @returns {Record} data about the activity */ success = (activityId, message) => { const time = Date.now() @@ -239,8 +246,8 @@ export class Reporter { if (activity.activity) { activity.activity.succeed(`${message} – ${time - activity.start}ms`) } else { - toLog.duration = time - activity.start - toLog.activity_id = activityId + toLog["duration"] = time - activity.start + toLog["activity_id"] = activityId this.loggerInstance_.log(toLog) } } else { @@ -295,6 +302,7 @@ export class Reporter { * A wrapper around winston's log method. */ log = (...args) => { + // @ts-ignore this.loggerInstance_.log(...args) } } diff --git a/packages/medusa-cli/src/reporter/panic-handler.js b/packages/medusa-cli/src/reporter/panic-handler.ts similarity index 65% rename from packages/medusa-cli/src/reporter/panic-handler.js rename to packages/medusa-cli/src/reporter/panic-handler.ts index 588e96b12a..514964985a 100644 --- a/packages/medusa-cli/src/reporter/panic-handler.js +++ b/packages/medusa-cli/src/reporter/panic-handler.ts @@ -1,14 +1,24 @@ -export const panicHandler = (panicData = {}) => { +export type PanicData = { + id: string + context: { + rootPath: string + path: string + } +} + +export enum PanicId { + InvalidProjectName = "10000", + InvalidPath = "10002", + AlreadyNodeProject = "10003", +} + +export const panicHandler = (panicData: PanicData = {} as PanicData) => { const { id, context } = panicData switch (id) { case "10000": return { message: `Looks like you provided a URL as your project name. Try "medusa new my-medusa-store ${context.rootPath}" instead.`, } - case "10001": - return { - message: `Looks like you provided a URL as your project name. Try "medusa new my-medusa-store ${context.rootPath}" instead.`, - } case "10002": return { message: `Could not create project because ${context.path} is not a valid path.`, diff --git a/packages/medusa-cli/src/util/package-manager.js b/packages/medusa-cli/src/util/package-manager.ts similarity index 57% rename from packages/medusa-cli/src/util/package-manager.js rename to packages/medusa-cli/src/util/package-manager.ts index 595e63f330..0cb270fe35 100644 --- a/packages/medusa-cli/src/util/package-manager.js +++ b/packages/medusa-cli/src/util/package-manager.ts @@ -1,22 +1,15 @@ import ConfigStore from "configstore" import reporter from "../reporter" -let config +const config = new ConfigStore(`medusa`, {}, { globalConfigPath: true }) const packageMangerConfigKey = `cli.packageManager` export const getPackageManager = () => { - if (!config) { - config = new ConfigStore(`medusa`, {}, { globalConfigPath: true }) - } - return config.get(packageMangerConfigKey) } -export const setPackageManager = packageManager => { - if (!config) { - config = new ConfigStore(`medusa`, {}, { globalConfigPath: true }) - } +export const setPackageManager = (packageManager) => { config.set(packageMangerConfigKey, packageManager) reporter.info(`Preferred package manager set to "${packageManager}"`) } diff --git a/packages/medusa-cli/src/util/token-store.js b/packages/medusa-cli/src/util/token-store.js deleted file mode 100644 index acf22ee424..0000000000 --- a/packages/medusa-cli/src/util/token-store.js +++ /dev/null @@ -1,20 +0,0 @@ -const ConfigStore = require("configstore") - -let config - -module.exports = { - getToken: function() { - if (!config) { - config = new ConfigStore(`medusa`, {}, { globalConfigPath: true }) - } - - return config.get("cloud.login_token") - }, - setToken: function(token) { - if (!config) { - config = new ConfigStore(`medusa`, {}, { globalConfigPath: true }) - } - - return config.set("cloud.login_token", token) - }, -} diff --git a/packages/medusa-cli/src/util/version.js b/packages/medusa-cli/src/util/version.js deleted file mode 100644 index 89686f7c1a..0000000000 --- a/packages/medusa-cli/src/util/version.js +++ /dev/null @@ -1,6 +0,0 @@ -import { getMedusaVersion } from "medusa-core-utils" - -export const getLocalMedusaVersion = () => { - const version = getMedusaVersion() - return version -} diff --git a/packages/medusa-cli/src/util/version.ts b/packages/medusa-cli/src/util/version.ts new file mode 100644 index 0000000000..088ea17ed8 --- /dev/null +++ b/packages/medusa-cli/src/util/version.ts @@ -0,0 +1,5 @@ +import { getMedusaVersion } from "medusa-core-utils" + +export const getLocalMedusaVersion = (): string => { + return getMedusaVersion() +} diff --git a/packages/medusa-cli/tsconfig.json b/packages/medusa-cli/tsconfig.json new file mode 100644 index 0000000000..731ef8a6e0 --- /dev/null +++ b/packages/medusa-cli/tsconfig.json @@ -0,0 +1,29 @@ +{ + "compilerOptions": { + "lib": ["es2020"], + "target": "es2020", + "outDir": "./dist", + "esModuleInterop": true, + "declaration": true, + "module": "commonjs", + "moduleResolution": "node", + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "sourceMap": true, + "noImplicitReturns": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "noImplicitThis": true, + "allowJs": true, + "skipLibCheck": true, + "downlevelIteration": true // to use ES5 specific tooling + }, + "include": ["src"], + "exclude": [ + "dist", + "./src/**/__tests__", + "./src/**/__mocks__", + "./src/**/__fixtures__", + "node_modules" + ] +} diff --git a/packages/medusa-cli/tsconfig.spec.json b/packages/medusa-cli/tsconfig.spec.json new file mode 100644 index 0000000000..9b62409191 --- /dev/null +++ b/packages/medusa-cli/tsconfig.spec.json @@ -0,0 +1,5 @@ +{ + "extends": "./tsconfig.json", + "include": ["src"], + "exclude": ["node_modules"] +} diff --git a/packages/medusa-core-utils/src/index.ts b/packages/medusa-core-utils/src/index.ts index e2858fbdc0..6e03eb2e4b 100644 --- a/packages/medusa-core-utils/src/index.ts +++ b/packages/medusa-core-utils/src/index.ts @@ -12,3 +12,4 @@ export * from "./medusa-container" export { parseCorsOrigins } from "./parse-cors-origins" export { transformIdableFields } from "./transform-idable-fields" export { default as zeroDecimalCurrencies } from "./zero-decimal-currencies" +export { getMedusaVersion } from "./get-medusa-version" diff --git a/packages/medusa-plugin-algolia/src/loaders/index.ts b/packages/medusa-plugin-algolia/src/loaders/index.ts index b814f13c62..321513fe38 100644 --- a/packages/medusa-plugin-algolia/src/loaders/index.ts +++ b/packages/medusa-plugin-algolia/src/loaders/index.ts @@ -1,4 +1,5 @@ -import { Logger, MedusaContainer } from "@medusajs/modules-sdk" +import { MedusaContainer } from "@medusajs/modules-sdk" +import { Logger } from "@medusajs/types" import AlgoliaService from "../services/algolia" import { AlgoliaPluginOptions } from "../types" diff --git a/packages/medusa-plugin-meilisearch/src/loaders/index.ts b/packages/medusa-plugin-meilisearch/src/loaders/index.ts index f98b65342e..f45cc98208 100644 --- a/packages/medusa-plugin-meilisearch/src/loaders/index.ts +++ b/packages/medusa-plugin-meilisearch/src/loaders/index.ts @@ -1,4 +1,5 @@ -import { Logger, MedusaContainer } from "@medusajs/modules-sdk" +import { MedusaContainer } from "@medusajs/modules-sdk" +import { Logger } from "@medusajs/types" import MeiliSearchService from "../services/meilisearch" import { MeilisearchPluginOptions } from "../types" diff --git a/packages/medusa/src/types/global.ts b/packages/medusa/src/types/global.ts index 9218ae2234..9c4f9e0541 100644 --- a/packages/medusa/src/types/global.ts +++ b/packages/medusa/src/types/global.ts @@ -1,7 +1,6 @@ import { CommonTypes } from "@medusajs/types" import { Request } from "express" import { MedusaContainer as coreMedusaContainer } from "medusa-core-utils" -import { Logger as _Logger } from "winston" import { Customer, User } from "../models" import { FindConfig, RequestQueryFields } from "./common" @@ -31,10 +30,20 @@ export type ClassConstructor = { export type MedusaContainer = coreMedusaContainer -export type Logger = _Logger & { - progress: (activityId: string, msg: string) => void - info: (msg: string) => void - warn: (msg: string) => void +export type Logger = { + panic: (data) => void + shouldLog: (level: string) => void + setLogLevel: (level: string) => void + unsetLogLevel: () => void + activity: (message: string, config?) => void + progress: (activityId, message) => void + error: (messageOrError, error?) => void + failure: (activityId, message) => void + success: (activityId, message) => void + debug: (message) => void + info: (message) => void + warn: (message) => void + log: (...args) => void } export type Constructor = new (...args: any[]) => T diff --git a/packages/product/src/scripts/migration-up.ts b/packages/product/src/scripts/migration-up.ts index e0139040a9..46b9d6090c 100644 --- a/packages/product/src/scripts/migration-up.ts +++ b/packages/product/src/scripts/migration-up.ts @@ -35,7 +35,7 @@ export async function runMigrations({ const migrator = orm.getMigrator() const pendingMigrations = await migrator.getPendingMigrations() - logger.info("Running pending migrations:", pendingMigrations) + logger.info(`Running pending migrations: ${pendingMigrations}`) await migrator.up({ migrations: pendingMigrations.map((m) => m.name), diff --git a/packages/types/src/bundles.ts b/packages/types/src/bundles.ts index 95114a9785..cc95cd0e83 100644 --- a/packages/types/src/bundles.ts +++ b/packages/types/src/bundles.ts @@ -8,3 +8,4 @@ export * as SearchTypes from "./search" export * as StockLocationTypes from "./stock-location" export * as TransactionBaseTypes from "./transaction-base" export * as DAL from "./dal" +export * as LoggerTypes from "./logger" diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 63df9857f3..c73f1c9a69 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -11,3 +11,4 @@ export * from "./shared-context" export * from "./stock-location" export * from "./transaction-base" export * from "./dal" +export * from "./logger" diff --git a/packages/types/src/logger/index.ts b/packages/types/src/logger/index.ts new file mode 100644 index 0000000000..83ddd1fc82 --- /dev/null +++ b/packages/types/src/logger/index.ts @@ -0,0 +1,15 @@ +export interface Logger { + panic: (data) => void + shouldLog: (level: string) => void + setLogLevel: (level: string) => void + unsetLogLevel: () => void + activity: (message: string, config?) => void + progress: (activityId, message) => void + error: (messageOrError, error?) => void + failure: (activityId, message) => void + success: (activityId, message) => void + debug: (message) => void + info: (message) => void + warn: (message) => void + log: (...args) => void +} diff --git a/packages/types/src/modules-sdk/index.ts b/packages/types/src/modules-sdk/index.ts index 13f20a065e..b6f14f7c48 100644 --- a/packages/types/src/modules-sdk/index.ts +++ b/packages/types/src/modules-sdk/index.ts @@ -1,5 +1,5 @@ -import { Logger as _Logger } from "winston" -import { MedusaContainer } from "../common/medusa-container" +import { MedusaContainer } from "../common" +import { Logger } from "../logger" export type Constructor = new (...args: any[]) => T export * from "../common/medusa-container" @@ -14,12 +14,6 @@ export type LogLevel = | "migration" export type LoggerOptions = boolean | "all" | LogLevel[] -export type Logger = _Logger & { - progress: (activityId: string, msg: string) => void - info: (msg: string) => void - warn: (msg: string) => void -} - export enum MODULE_SCOPE { INTERNAL = "internal", EXTERNAL = "external", diff --git a/yarn.lock b/yarn.lock index 591ebf22da..77c5299687 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6238,12 +6238,8 @@ __metadata: version: 0.0.0-use.local resolution: "@medusajs/medusa-cli@workspace:packages/medusa-cli" dependencies: - "@babel/cli": ^7.7.5 - "@babel/core": ^7.7.5 - "@babel/plugin-proposal-class-properties": ^7.7.4 - "@babel/plugin-transform-runtime": ^7.7.6 - "@babel/preset-env": ^7.7.5 "@medusajs/utils": ^1.9.1 + "@types/yargs": ^15.0.15 axios: ^0.21.4 chalk: ^4.0.0 configstore: 5.0.1 @@ -6269,8 +6265,9 @@ __metadata: resolve-cwd: ^3.0.0 semver: ^7.3.8 stack-trace: ^0.0.10 + ts-jest: ^25.5.1 + typescript: ^4.9.5 ulid: ^2.3.0 - url: ^0.11.0 winston: ^3.8.2 yargs: ^15.3.1 bin: @@ -12623,6 +12620,15 @@ __metadata: languageName: node linkType: hard +"@types/yargs@npm:^15.0.15": + version: 15.0.15 + resolution: "@types/yargs@npm:15.0.15" + dependencies: + "@types/yargs-parser": "*" + checksum: b52519ba68a8d90996b54143ff74fcd8ac1722a1ef4a50ed8c3dbc1f7a76d14210f0262f8b91eabcdab202ff4babdd92ce7332ab1cdd6af4eae7c9fc81c83797 + languageName: node + linkType: hard + "@types/yargs@npm:^16.0.0": version: 16.0.4 resolution: "@types/yargs@npm:16.0.4"