Adds Middleware API (#40)
* Adds test project * Adds e2e for end-2-end tests * Update gitignore * Update loaders * Creates test project * v0.1.27 * Upgrade * dependency fixes * Load project plugins in the plugin loader * Issue with instanceof * Fixes versioning issues * Adds medusa middleware api * Adds documentation * Fixes tests
This commit is contained in:
21
e2e/prod-project/.babelrc.js
Normal file
21
e2e/prod-project/.babelrc.js
Normal file
@@ -0,0 +1,21 @@
|
||||
let ignore = [`**/dist`]
|
||||
|
||||
// Jest needs to compile this code, but generally we don't want this copied
|
||||
// to output folders
|
||||
if (process.env.NODE_ENV !== `test`) {
|
||||
ignore.push(`**/__tests__`)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
plugins: [
|
||||
"@babel/plugin-proposal-class-properties",
|
||||
"@babel/plugin-transform-instanceof",
|
||||
],
|
||||
presets: ["@babel/preset-env"],
|
||||
env: {
|
||||
test: {
|
||||
plugins: ["@babel/plugin-transform-runtime"],
|
||||
},
|
||||
},
|
||||
ignore,
|
||||
}
|
||||
9
e2e/prod-project/.eslintrc
Normal file
9
e2e/prod-project/.eslintrc
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"plugins": ["prettier"],
|
||||
"extends": ["prettier"],
|
||||
"rules": {
|
||||
"prettier/prettier": "error",
|
||||
"semi": "error",
|
||||
"no-unused-expressions": "true"
|
||||
}
|
||||
}
|
||||
3
e2e/prod-project/.gitignore
vendored
Normal file
3
e2e/prod-project/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
/node_modules
|
||||
.env
|
||||
|
||||
8
e2e/prod-project/.prettierrc
Normal file
8
e2e/prod-project/.prettierrc
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"endOfLine": "lf",
|
||||
"semi": false,
|
||||
"singleQuote": false,
|
||||
"tabWidth": 2,
|
||||
"trailingComma": "es5"
|
||||
}
|
||||
|
||||
3
e2e/prod-project/medusa-config.js
Normal file
3
e2e/prod-project/medusa-config.js
Normal file
@@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
plugins: [`medusa-payment-stripe`, `medusa-plugin-permissions`],
|
||||
}
|
||||
36
e2e/prod-project/package.json
Normal file
36
e2e/prod-project/package.json
Normal file
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "prod-project",
|
||||
"version": "1.0.0",
|
||||
"description": "Test project for testing production setup",
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
"url": "https://github.com/medusajs/medusa",
|
||||
"directory": "e2e/prod-project"
|
||||
},
|
||||
"author": "Sebastian Rindom",
|
||||
"license": "GPL-3.0",
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.7.5",
|
||||
"@babel/core": "^7.7.5",
|
||||
"@babel/node": "^7.7.4",
|
||||
"@babel/plugin-proposal-class-properties": "^7.7.4",
|
||||
"@babel/plugin-transform-instanceof": "^7.8.3",
|
||||
"@babel/plugin-transform-runtime": "^7.7.6",
|
||||
"@babel/preset-env": "^7.7.5",
|
||||
"@babel/register": "^7.7.4",
|
||||
"@babel/runtime": "^7.7.6",
|
||||
"cross-env": "^5.2.1",
|
||||
"eslint": "^6.7.2",
|
||||
"jest": "^24.9.0",
|
||||
"nodemon": "^2.0.1",
|
||||
"prettier": "^2.0.2",
|
||||
"supertest": "^4.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"express": "^4.17.1",
|
||||
"medusa-payment-stripe": "^0.1.27"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "nodemon --watch plugins/ --watch src/ --exec babel-node node_modules/@medusajs/medusa/dist/app.js"
|
||||
}
|
||||
}
|
||||
17
e2e/prod-project/src/api/index.js
Normal file
17
e2e/prod-project/src/api/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
import { Router } from "express"
|
||||
|
||||
export default () => {
|
||||
const app = Router()
|
||||
|
||||
app.get("/project-root", async (req, res, next) => {
|
||||
try {
|
||||
const testService = req.scope.resolve("testService")
|
||||
const newHi = await testService.sayHi()
|
||||
res.status(200).json(newHi)
|
||||
} catch (e) {
|
||||
next(e)
|
||||
}
|
||||
})
|
||||
|
||||
return app
|
||||
}
|
||||
12
e2e/prod-project/src/models/test.js
Normal file
12
e2e/prod-project/src/models/test.js
Normal file
@@ -0,0 +1,12 @@
|
||||
import mongoose from "mongoose"
|
||||
import { BaseModel } from "medusa-interfaces"
|
||||
|
||||
class TestModel extends BaseModel {
|
||||
static modelName = "test"
|
||||
|
||||
static schema = {
|
||||
title: { type: String, required: true },
|
||||
}
|
||||
}
|
||||
|
||||
export default TestModel
|
||||
16
e2e/prod-project/src/services/test.js
Normal file
16
e2e/prod-project/src/services/test.js
Normal file
@@ -0,0 +1,16 @@
|
||||
import { BaseService } from "medusa-interfaces"
|
||||
|
||||
class TestService extends BaseService {
|
||||
constructor({ testModel }) {
|
||||
super()
|
||||
|
||||
this.testModel_ = testModel
|
||||
}
|
||||
|
||||
async sayHi() {
|
||||
const res = await this.testModel_.create({ title: "hi" })
|
||||
return res
|
||||
}
|
||||
}
|
||||
|
||||
export default TestService
|
||||
5747
e2e/prod-project/yarn.lock
Normal file
5747
e2e/prod-project/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
9
packages/medusa-core-utils/.eslintrc
Normal file
9
packages/medusa-core-utils/.eslintrc
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"plugins": ["prettier"],
|
||||
"extends": ["prettier"],
|
||||
"rules": {
|
||||
"prettier/prettier": "error",
|
||||
"semi": "error",
|
||||
"no-unused-expressions": "true"
|
||||
}
|
||||
}
|
||||
7
packages/medusa-core-utils/.prettierrc
Normal file
7
packages/medusa-core-utils/.prettierrc
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"endOfLine": "lf",
|
||||
"semi": false,
|
||||
"singleQuote": false,
|
||||
"tabWidth": 2,
|
||||
"trailingComma": "es5"
|
||||
}
|
||||
@@ -19,11 +19,14 @@
|
||||
"@babel/cli": "^7.7.5",
|
||||
"@babel/core": "^7.7.5",
|
||||
"@babel/plugin-proposal-class-properties": "^7.7.4",
|
||||
"@babel/plugin-transform-classes": "^7.9.5",
|
||||
"@babel/plugin-transform-runtime": "^7.7.6",
|
||||
"@babel/preset-env": "^7.7.5",
|
||||
"@babel/runtime": "^7.9.6",
|
||||
"cross-env": "^5.2.1",
|
||||
"eslint": "^6.8.0",
|
||||
"jest": "^25.5.2",
|
||||
"eslint": "^6.8.0"
|
||||
"prettier": "^1.19.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hapi/joi": "^16.1.8",
|
||||
|
||||
18
packages/medusa-core-utils/src/create-require-from-path.js
Normal file
18
packages/medusa-core-utils/src/create-require-from-path.js
Normal file
@@ -0,0 +1,18 @@
|
||||
import Module from "module"
|
||||
import path from "path"
|
||||
|
||||
const fallback = filename => {
|
||||
const mod = new Module(filename)
|
||||
|
||||
mod.filename = filename
|
||||
mod.paths = Module._nodeModulePaths(path.dirname(filename))
|
||||
mod._compile(`module.exports = require;`, filename)
|
||||
|
||||
return mod.exports
|
||||
}
|
||||
|
||||
// Polyfill Node's `Module.createRequireFromPath` if not present (added in Node v10.12.0)
|
||||
const createRequireFromPath =
|
||||
Module.createRequire || Module.createRequireFromPath || fallback
|
||||
|
||||
export default createRequireFromPath
|
||||
23
packages/medusa-core-utils/src/get-config-file.js
Normal file
23
packages/medusa-core-utils/src/get-config-file.js
Normal file
@@ -0,0 +1,23 @@
|
||||
import path from "path"
|
||||
|
||||
/**
|
||||
* Attempts to resolve the config file in a given root directory.
|
||||
* @param {string} rootDir - the directory to find the config file in.
|
||||
* @param {string} configName - the name of the config file.
|
||||
* @return {object} an object containing the config module and its path.
|
||||
*/
|
||||
function getConfigFile(rootDir, configName) {
|
||||
const configPath = path.join(rootDir, configName)
|
||||
let configFilePath = ``
|
||||
let configModule
|
||||
try {
|
||||
configFilePath = require.resolve(configPath)
|
||||
configModule = require(configFilePath)
|
||||
} catch (err) {
|
||||
return {}
|
||||
}
|
||||
|
||||
return { configModule, configFilePath }
|
||||
}
|
||||
|
||||
export default getConfigFile
|
||||
@@ -1,2 +1,4 @@
|
||||
export { default as Validator } from "./validator"
|
||||
export { default as MedusaError } from "./errors"
|
||||
export { default as getConfigFile } from "./get-config-file"
|
||||
export { default as createRequireFromPath } from "./create-require-from-path"
|
||||
|
||||
@@ -559,6 +559,20 @@
|
||||
"@babel/helper-split-export-declaration" "^7.8.3"
|
||||
globals "^11.1.0"
|
||||
|
||||
"@babel/plugin-transform-classes@^7.9.5":
|
||||
version "7.9.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.9.5.tgz#800597ddb8aefc2c293ed27459c1fcc935a26c2c"
|
||||
integrity sha512-x2kZoIuLC//O5iA7PEvecB105o7TLzZo8ofBVhP79N+DO3jaX+KYfww9TQcfBEZD0nikNyYcGB1IKtRq36rdmg==
|
||||
dependencies:
|
||||
"@babel/helper-annotate-as-pure" "^7.8.3"
|
||||
"@babel/helper-define-map" "^7.8.3"
|
||||
"@babel/helper-function-name" "^7.9.5"
|
||||
"@babel/helper-optimise-call-expression" "^7.8.3"
|
||||
"@babel/helper-plugin-utils" "^7.8.3"
|
||||
"@babel/helper-replace-supers" "^7.8.6"
|
||||
"@babel/helper-split-export-declaration" "^7.8.3"
|
||||
globals "^11.1.0"
|
||||
|
||||
"@babel/plugin-transform-computed-properties@^7.8.3":
|
||||
version "7.8.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.8.3.tgz#96d0d28b7f7ce4eb5b120bb2e0e943343c86f81b"
|
||||
@@ -880,7 +894,7 @@
|
||||
globals "^11.1.0"
|
||||
lodash "^4.17.13"
|
||||
|
||||
"@babel/types@^7.0.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.8.6", "@babel/types@^7.9.0", "@babel/types@^7.9.5", "@babel/types@^7.9.6":
|
||||
"@babel/types@^7.0.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.9.0", "@babel/types@^7.9.6":
|
||||
version "7.9.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.9.6.tgz#2c5502b427251e9de1bd2dff95add646d95cc9f7"
|
||||
integrity sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA==
|
||||
@@ -898,6 +912,15 @@
|
||||
lodash "^4.17.13"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@babel/types@^7.8.6", "@babel/types@^7.9.5":
|
||||
version "7.9.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.9.5.tgz#89231f82915a8a566a703b3b20133f73da6b9444"
|
||||
integrity sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==
|
||||
dependencies:
|
||||
"@babel/helper-validator-identifier" "^7.9.5"
|
||||
lodash "^4.17.13"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@bcoe/v8-coverage@^0.2.3":
|
||||
version "0.2.3"
|
||||
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
|
||||
@@ -3849,6 +3872,11 @@ prelude-ls@~1.1.2:
|
||||
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
|
||||
integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=
|
||||
|
||||
prettier@^1.19.1:
|
||||
version "1.19.1"
|
||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb"
|
||||
integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==
|
||||
|
||||
pretty-format@^25.5.0:
|
||||
version "25.5.0"
|
||||
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-25.5.0.tgz#7873c1d774f682c34b8d48b6743a2bf2ac55791a"
|
||||
|
||||
@@ -16,10 +16,11 @@
|
||||
"@babel/plugin-proposal-class-properties": "^7.7.4",
|
||||
"@babel/plugin-transform-runtime": "^7.7.6",
|
||||
"@babel/preset-env": "^7.7.5",
|
||||
"@babel/runtime": "^7.9.6",
|
||||
"client-sessions": "^0.8.0",
|
||||
"cross-env": "^5.2.1",
|
||||
"jest": "^25.5.2",
|
||||
"eslint": "^6.8.0"
|
||||
"eslint": "^6.8.0",
|
||||
"jest": "^25.5.2"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "babel src --out-dir . --ignore **/__tests__",
|
||||
@@ -27,8 +28,11 @@
|
||||
"watch": "babel -w src --out-dir . --ignore **/__tests__"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/plugin-transform-classes": "^7.9.5",
|
||||
"@babel/plugin-transform-instanceof": "^7.8.3",
|
||||
"@babel/runtime": "^7.7.6",
|
||||
"express": "^4.17.1",
|
||||
"medusa-core-utils": "^0.3.0",
|
||||
"medusa-interfaces": "^0.1.27-alpha.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
{
|
||||
"plugins": ["@babel/plugin-proposal-class-properties"],
|
||||
"plugins": [
|
||||
"@babel/plugin-proposal-class-properties",
|
||||
"@babel/plugin-transform-instanceof"
|
||||
],
|
||||
"presets": ["@babel/preset-env"],
|
||||
"env": {
|
||||
"test": {
|
||||
|
||||
@@ -19,15 +19,19 @@
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.7.5",
|
||||
"@babel/core": "^7.7.5",
|
||||
"@babel/plugin-transform-classes": "^7.9.5",
|
||||
"@babel/plugin-proposal-class-properties": "^7.7.4",
|
||||
"@babel/plugin-transform-instanceof": "^7.8.3",
|
||||
"@babel/plugin-transform-runtime": "^7.7.6",
|
||||
"@babel/preset-env": "^7.7.5",
|
||||
"@babel/runtime": "^7.9.6",
|
||||
"cross-env": "^5.2.1",
|
||||
"eslint": "^6.8.0",
|
||||
"jest": "^25.5.2",
|
||||
"prettier": "^1.19.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"medusa-core-utils": "^0.3.0",
|
||||
"mongoose": "^5.8.0"
|
||||
},
|
||||
"gitHead": "35e0930650d5f4aedf2610749cd131ae8b7e17cc"
|
||||
|
||||
@@ -16,10 +16,11 @@
|
||||
"@babel/plugin-proposal-class-properties": "^7.7.4",
|
||||
"@babel/plugin-transform-runtime": "^7.7.6",
|
||||
"@babel/preset-env": "^7.7.5",
|
||||
"@babel/runtime": "^7.9.6",
|
||||
"client-sessions": "^0.8.0",
|
||||
"cross-env": "^5.2.1",
|
||||
"jest": "^25.5.2",
|
||||
"eslint": "^6.8.0"
|
||||
"eslint": "^6.8.0",
|
||||
"jest": "^25.5.2"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "babel src --out-dir . --ignore **/__tests__",
|
||||
@@ -27,9 +28,11 @@
|
||||
"watch": "babel -w src --out-dir . --ignore **/__tests__"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/plugin-transform-classes": "^7.9.5",
|
||||
"@babel/plugin-transform-instanceof": "^7.8.3",
|
||||
"@babel/runtime": "^7.7.6",
|
||||
"express": "^4.17.1",
|
||||
"medusa-core-utils": "^0.3.0",
|
||||
"medusa-interfaces": "^0.3.0"
|
||||
},
|
||||
"gitHead": "35e0930650d5f4aedf2610749cd131ae8b7e17cc"
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
{
|
||||
"plugins": ["@babel/plugin-proposal-class-properties"],
|
||||
"plugins": [
|
||||
"@babel/plugin-proposal-class-properties",
|
||||
"@babel/plugin-transform-classes",
|
||||
"@babel/plugin-transform-instanceof"
|
||||
],
|
||||
"presets": ["@babel/preset-env"],
|
||||
"env": {
|
||||
"test": {
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
"directory": "packages/medusa-plugin-permissions"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "babel src --out-dir dist/ --ignore **/__tests__",
|
||||
"build": "babel src --out-dir . --ignore **/__tests__",
|
||||
"prepare": "cross-env NODE_ENV=production npm run build",
|
||||
"watch": "babel -w src --out-dir dist/ --ignore **/__tests__",
|
||||
"watch": "babel -w src --out-dir . --ignore **/__tests__",
|
||||
"test": "jest"
|
||||
},
|
||||
"author": "Oliver Juhl",
|
||||
@@ -20,6 +20,8 @@
|
||||
"@babel/cli": "^7.7.5",
|
||||
"@babel/core": "^7.7.5",
|
||||
"@babel/plugin-proposal-class-properties": "^7.7.4",
|
||||
"@babel/plugin-transform-classes": "^7.9.5",
|
||||
"@babel/plugin-transform-instanceof": "^7.8.3",
|
||||
"@babel/plugin-transform-runtime": "^7.7.6",
|
||||
"@babel/preset-env": "^7.7.5",
|
||||
"@babel/runtime": "^7.7.6",
|
||||
@@ -27,9 +29,9 @@
|
||||
"jest": "^25.5.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"medusa-core-utils": "^1.0.0",
|
||||
"medusa-interfaces": "^1.0.0",
|
||||
"medusa-test-utils": "^1.0.0",
|
||||
"medusa-core-utils": "^0.3.0",
|
||||
"medusa-interfaces": "^0.3.0",
|
||||
"medusa-test-utils": "^0.3.0",
|
||||
"mongoose": "^5.8.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
// This middleware is injected to ensure authorization of requests
|
||||
// Since this middleware uses the user object on the request, this should be
|
||||
// injected after authentication in the core middleware, hence we name
|
||||
// the middleware postAuth.
|
||||
export default {
|
||||
postAuthentication: () => {
|
||||
return (err, req, res, next) => {
|
||||
const permissionService = req.scope.resolve("permissionService")
|
||||
if (permissionService.hasPermission(req.user, req.method, req.path)) {
|
||||
next()
|
||||
} else {
|
||||
res.status(422)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
// This middleware is injected to ensure authorization of requests
|
||||
// Since this middleware uses the user object on the request, this should be
|
||||
// injected after authentication in the core middleware, hence we name
|
||||
// the middleware postAuth.
|
||||
export default postAuth = () => {
|
||||
return (err, req, res, next) => {
|
||||
const permissionService = req.scope.resolve("permissionService")
|
||||
if (permissionService.hasPermission(req.user, req.method, req.path)) {
|
||||
next()
|
||||
} else {
|
||||
res.status(422)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -55,6 +55,7 @@ class PermissionService extends BaseService {
|
||||
}
|
||||
|
||||
async hasPermission(user, method, endpoint) {
|
||||
if (!user) return false
|
||||
for (let i = 0; i < user.metadata.roles.length; i++) {
|
||||
const role = user.metadata.roles[i]
|
||||
const permissions = await this.retrieveRole(role)
|
||||
|
||||
@@ -21,11 +21,14 @@
|
||||
"@babel/plugin-proposal-class-properties": "^7.7.4",
|
||||
"@babel/plugin-transform-runtime": "^7.7.6",
|
||||
"@babel/preset-env": "^7.7.5",
|
||||
"@babel/runtime": "^7.9.6",
|
||||
"cross-env": "^5.2.1",
|
||||
"jest": "^25.5.2",
|
||||
"eslint": "^6.8.0"
|
||||
"eslint": "^6.8.0",
|
||||
"jest": "^25.5.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/plugin-transform-classes": "^7.9.5",
|
||||
"medusa-core-utils": "^0.3.0",
|
||||
"mongoose": "^5.8.0"
|
||||
},
|
||||
"gitHead": "35e0930650d5f4aedf2610749cd131ae8b7e17cc"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,11 @@ if (process.env.NODE_ENV !== `test`) {
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
plugins: ["@babel/plugin-proposal-class-properties"],
|
||||
plugins: [
|
||||
"@babel/plugin-proposal-class-properties",
|
||||
"@babel/plugin-transform-classes",
|
||||
"@babel/plugin-transform-instanceof",
|
||||
],
|
||||
presets: ["@babel/preset-env"],
|
||||
env: {
|
||||
test: {
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
module.exports = {
|
||||
plugins: [],
|
||||
}
|
||||
@@ -18,6 +18,7 @@
|
||||
"@babel/core": "^7.7.5",
|
||||
"@babel/node": "^7.7.4",
|
||||
"@babel/plugin-proposal-class-properties": "^7.7.4",
|
||||
"@babel/plugin-transform-instanceof": "^7.8.3",
|
||||
"@babel/plugin-transform-runtime": "^7.7.6",
|
||||
"@babel/preset-env": "^7.7.5",
|
||||
"@babel/register": "^7.7.4",
|
||||
@@ -31,12 +32,14 @@
|
||||
},
|
||||
"scripts": {
|
||||
"start": "nodemon --watch plugins/ --watch src/ --exec babel-node src/app.js",
|
||||
"watch": "babel -w src --out-dir dist --ignore **/__tests__",
|
||||
"prepare": "cross-env NODE_ENV=production npm run build",
|
||||
"build": "babel src -d dist",
|
||||
"serve": "node dist/app.js",
|
||||
"test": "jest"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/plugin-transform-classes": "^7.9.5",
|
||||
"@hapi/joi": "^16.1.8",
|
||||
"awilix": "^4.2.3",
|
||||
"bcrypt": "^3.0.7",
|
||||
|
||||
@@ -4,11 +4,11 @@ import store from "./routes/store"
|
||||
import errorHandler from "./middlewares/error-handler"
|
||||
|
||||
// guaranteed to get dependencies
|
||||
export default () => {
|
||||
export default container => {
|
||||
const app = Router()
|
||||
|
||||
admin(app)
|
||||
store(app)
|
||||
admin(app, container)
|
||||
store(app, container)
|
||||
|
||||
app.use(errorHandler())
|
||||
|
||||
|
||||
@@ -11,15 +11,23 @@ import discountRoutes from "./discounts"
|
||||
|
||||
const route = Router()
|
||||
|
||||
export default app => {
|
||||
export default (app, container) => {
|
||||
const middlewareService = container.resolve("middlewareService")
|
||||
|
||||
app.use("/admin", route)
|
||||
|
||||
// Unauthenticated routes
|
||||
authRoutes(route)
|
||||
|
||||
// Calls all middleware that has been registered to run before authentication.
|
||||
middlewareService.usePreAuthentication(app)
|
||||
|
||||
// Authenticated routes
|
||||
route.use(middlewares.authenticate())
|
||||
|
||||
// Calls all middleware that has been registered to run after authentication.
|
||||
middlewareService.usePostAuthentication(app)
|
||||
|
||||
productRoutes(route)
|
||||
userRoutes(route)
|
||||
regionRoutes(route)
|
||||
|
||||
@@ -29,7 +29,7 @@ testApp.use((req, res, next) => {
|
||||
next()
|
||||
})
|
||||
|
||||
apiLoader({ app: testApp })
|
||||
apiLoader({ container, app: testApp })
|
||||
|
||||
const supertestRequest = supertest(testApp)
|
||||
|
||||
|
||||
@@ -3,18 +3,7 @@ import routes from "../api"
|
||||
import glob from "glob"
|
||||
import path from "path"
|
||||
|
||||
export default async ({ app }) => {
|
||||
const corePath = path.join(__dirname, "../api")
|
||||
const appPath = path.resolve("src/api")
|
||||
|
||||
if (corePath !== appPath) {
|
||||
const appRoutes = require(appPath).default
|
||||
if (appRoutes) {
|
||||
app.use("/", appRoutes())
|
||||
}
|
||||
}
|
||||
|
||||
app.use("/", routes())
|
||||
|
||||
export default async ({ app, container }) => {
|
||||
app.use("/", routes(container))
|
||||
return app
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ export default async ({ expressApp }) => {
|
||||
await servicesLoader({ container })
|
||||
Logger.info("Services initialized")
|
||||
|
||||
await mongooseLoader()
|
||||
await mongooseLoader({ container })
|
||||
Logger.info("MongoDB Intialized")
|
||||
|
||||
await expressLoader({ app: expressApp })
|
||||
@@ -54,7 +54,7 @@ export default async ({ expressApp }) => {
|
||||
await pluginsLoader({ container, app: expressApp })
|
||||
Logger.info("Plugins Intialized")
|
||||
|
||||
await apiLoader({ app: expressApp })
|
||||
await apiLoader({ container, app: expressApp })
|
||||
Logger.info("API initialized")
|
||||
}
|
||||
|
||||
|
||||
@@ -9,10 +9,7 @@ import { asFunction } from "awilix"
|
||||
*/
|
||||
export default ({ container }) => {
|
||||
let corePath = "../models/*.js"
|
||||
let appPath = "src/models/*.js"
|
||||
|
||||
const coreFull = path.join(__dirname, corePath)
|
||||
const appFull = path.resolve(appPath)
|
||||
|
||||
const core = glob.sync(coreFull, { cwd: __dirname })
|
||||
core.forEach(fn => {
|
||||
@@ -22,25 +19,6 @@ export default ({ container }) => {
|
||||
[name]: asFunction(cradle => new loaded(cradle)).singleton(),
|
||||
})
|
||||
})
|
||||
|
||||
if (coreFull !== appFull) {
|
||||
const files = glob.sync(appFull)
|
||||
files.forEach(fn => {
|
||||
const loaded = require(fn).default
|
||||
|
||||
if (!(loaded.prototype instanceof BaseModel)) {
|
||||
const logger = container.resolve("logger")
|
||||
const message = `Models must inherit from BaseModel, please check ${fn}`
|
||||
logger.error(message)
|
||||
throw new Error(message)
|
||||
}
|
||||
|
||||
const name = formatRegistrationName(fn)
|
||||
container.register({
|
||||
[name]: asFunction(cradle => new loaded(cradle)).singleton(),
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function formatRegistrationName(fn) {
|
||||
|
||||
@@ -1,11 +1,19 @@
|
||||
import mongoose from "mongoose"
|
||||
import config from "../config"
|
||||
|
||||
export default async () => {
|
||||
const connection = await mongoose.connect(config.databaseURL, {
|
||||
useNewUrlParser: true,
|
||||
useCreateIndex: true,
|
||||
useUnifiedTopology: true,
|
||||
export default async ({ container }) => {
|
||||
const logger = container.resolve("logger")
|
||||
await mongoose
|
||||
.connect(config.databaseURL, {
|
||||
useNewUrlParser: true,
|
||||
useCreateIndex: true,
|
||||
useUnifiedTopology: true,
|
||||
})
|
||||
.catch(err => {
|
||||
logger.error(err)
|
||||
})
|
||||
|
||||
mongoose.connection.on("error", err => {
|
||||
logger.error(err)
|
||||
})
|
||||
return connection.connection.db
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
PaymentService,
|
||||
FulfillmentService,
|
||||
} from "medusa-interfaces"
|
||||
import { getConfigFile, createRequireFromPath } from "medusa-core-utils"
|
||||
import _ from "lodash"
|
||||
import path from "path"
|
||||
import fs from "fs"
|
||||
@@ -15,8 +16,16 @@ import { sync as existsSync } from "fs-exists-cached"
|
||||
* Registers all services in the services directory
|
||||
*/
|
||||
export default ({ container, app }) => {
|
||||
const configPath = path.resolve("./medusa-config")
|
||||
const { plugins } = require(configPath)
|
||||
const { configModule, configFilePath } = getConfigFile(
|
||||
process.cwd(),
|
||||
`medusa-config`
|
||||
)
|
||||
|
||||
if (!configModule) {
|
||||
return
|
||||
}
|
||||
|
||||
const { plugins } = configModule
|
||||
|
||||
const resolved = plugins.map(plugin => {
|
||||
if (_.isString(plugin)) {
|
||||
@@ -29,13 +38,53 @@ export default ({ container, app }) => {
|
||||
return details
|
||||
})
|
||||
|
||||
resolved.push({
|
||||
resolve: process.cwd(),
|
||||
name: `project-plugin`,
|
||||
id: createPluginId(`project-plugin`),
|
||||
options: {},
|
||||
version: createFileContentHash(process.cwd(), `**`),
|
||||
})
|
||||
|
||||
resolved.forEach(pluginDetails => {
|
||||
registerServices(pluginDetails, container)
|
||||
registerModels(pluginDetails, container)
|
||||
registerServices(pluginDetails, container)
|
||||
registerMedusaApi(pluginDetails, container)
|
||||
registerApi(pluginDetails, app)
|
||||
})
|
||||
}
|
||||
|
||||
function registerMedusaApi(pluginDetails, container) {
|
||||
registerMedusaMiddleware(pluginDetails, container)
|
||||
}
|
||||
|
||||
function registerMedusaMiddleware(pluginDetails, container) {
|
||||
let module
|
||||
try {
|
||||
module = require(`${pluginDetails.resolve}/api/medusa-middleware`).default
|
||||
} catch (err) {
|
||||
return
|
||||
}
|
||||
|
||||
const middlewareService = container.resolve("middlewareService")
|
||||
if (module.postAuthentication) {
|
||||
middlewareService.addPostAuthentication(
|
||||
module.postAuthentication,
|
||||
pluginDetails.options
|
||||
)
|
||||
}
|
||||
|
||||
if (module.preAuthentication) {
|
||||
middlewareService.addPreAuthentication(
|
||||
module.preAuthentication,
|
||||
pluginDetails.options
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the plugin's api routes.
|
||||
*/
|
||||
function registerApi(pluginDetails, app) {
|
||||
try {
|
||||
const routes = require(`${pluginDetails.resolve}/api`).default
|
||||
@@ -59,7 +108,7 @@ function registerApi(pluginDetails, app) {
|
||||
* @return {void}
|
||||
*/
|
||||
function registerServices(pluginDetails, container) {
|
||||
const files = glob.sync(`${pluginDetails.resolve}/services/*`, {})
|
||||
const files = glob.sync(`${pluginDetails.resolve}/services/[!__]*`, {})
|
||||
files.forEach(fn => {
|
||||
const loaded = require(fn).default
|
||||
|
||||
@@ -119,9 +168,10 @@ function registerServices(pluginDetails, container) {
|
||||
* @return {void}
|
||||
*/
|
||||
function registerModels(pluginDetails, container) {
|
||||
const files = glob.sync(`${pluginDetails.resolve}/models/*`, {})
|
||||
const files = glob.sync(`${pluginDetails.resolve}/models/*.js`, {})
|
||||
files.forEach(fn => {
|
||||
const loaded = require(fn).default
|
||||
|
||||
if (!(loaded.prototype instanceof BaseModel)) {
|
||||
const logger = container.resolve("logger")
|
||||
const message = `Models must inherit from BaseModel, please check ${fn}`
|
||||
@@ -131,7 +181,9 @@ function registerModels(pluginDetails, container) {
|
||||
|
||||
const name = formatRegistrationName(fn)
|
||||
container.register({
|
||||
[name]: asFunction(cradle => new loaded(cradle, pluginDetails.options)),
|
||||
[name]: asFunction(
|
||||
cradle => new loaded(cradle, pluginDetails.options)
|
||||
).singleton(),
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -201,15 +253,22 @@ function resolvePlugin(pluginName) {
|
||||
}
|
||||
}
|
||||
|
||||
const rootDir = path.resolve(".")
|
||||
|
||||
/**
|
||||
* Here we have an absolute path to an internal plugin, or a name of a module
|
||||
* which should be located in node_modules.
|
||||
*/
|
||||
try {
|
||||
const requireSource =
|
||||
rootDir !== null
|
||||
? createRequireFromPath(`${rootDir}/:internal:`)
|
||||
: require
|
||||
|
||||
// If the path is absolute, resolve the directory of the internal plugin,
|
||||
// otherwise resolve the directory containing the package.json
|
||||
const resolvedPath = path.dirname(
|
||||
require.resolve(`${pluginName}/package.json`)
|
||||
requireSource.resolve(`${pluginName}/package.json`)
|
||||
)
|
||||
|
||||
const packageJSON = JSON.parse(
|
||||
@@ -229,3 +288,7 @@ function resolvePlugin(pluginName) {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
function createFileContentHash(path, files) {
|
||||
return path + files
|
||||
}
|
||||
|
||||
@@ -1,65 +1,25 @@
|
||||
import { BaseService, PaymentService } from "medusa-interfaces"
|
||||
import glob from "glob"
|
||||
import path from "path"
|
||||
import { Lifetime } from "awilix"
|
||||
import { asFunction } from "awilix"
|
||||
import { Lifetime, asFunction } from "awilix"
|
||||
|
||||
/**
|
||||
* Registers all services in the services directory
|
||||
*/
|
||||
export default ({ container }) => {
|
||||
let corePath = "../services/*.js"
|
||||
let appPath = "src/services/*.js"
|
||||
|
||||
if (process.env.NODE_ENV === "test") {
|
||||
corePath = "../services/__mocks__/*.js"
|
||||
appPath = "src/services/__mocks__/*.js"
|
||||
}
|
||||
const isTest = process.env.NODE_ENV === "test"
|
||||
|
||||
const corePath = isTest ? "../services/__mocks__/*.js" : "../services/*.js"
|
||||
const coreFull = path.join(__dirname, corePath)
|
||||
const appFull = path.resolve(appPath)
|
||||
|
||||
const core = glob.sync(coreFull, { cwd: __dirname })
|
||||
core.forEach(fn => {
|
||||
const loaded = require(fn).default
|
||||
const name = formatRegistrationName(fn)
|
||||
container.register({
|
||||
[name]: asFunction(cradle => new loaded(cradle)),
|
||||
[name]: asFunction(cradle => new loaded(cradle)).singleton(),
|
||||
})
|
||||
})
|
||||
|
||||
if (coreFull !== appFull) {
|
||||
const files = glob.sync(appFull)
|
||||
files.forEach(fn => {
|
||||
const loaded = require(fn).default
|
||||
|
||||
if (!(loaded.prototype instanceof BaseService)) {
|
||||
const logger = container.resolve("logger")
|
||||
const message = `Models must inherit from BaseModel, please check ${fn}`
|
||||
logger.error(message)
|
||||
throw new Error(message)
|
||||
}
|
||||
|
||||
if (loaded.prototype instanceof PaymentService) {
|
||||
// Register our payment providers to paymentProviders
|
||||
container.registerAdd(
|
||||
"paymentProviders",
|
||||
asFunction(cradle => new loaded(cradle))
|
||||
)
|
||||
|
||||
// Add the service directly to the container in order to make simple
|
||||
// resolution if we already know which payment provider we need to use
|
||||
container.register({
|
||||
[`pp_${loaded.identifier}`]: asFunction(cradle => new loaded(cradle)),
|
||||
})
|
||||
} else {
|
||||
const name = formatRegistrationName(fn)
|
||||
container.register({
|
||||
[name]: asFunction(cradle => new loaded(cradle)),
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function formatRegistrationName(fn) {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import mongoose from "mongoose"
|
||||
import { BaseModel } from "medusa-interfaces"
|
||||
import DiscountRule from "./schemas/discount-rule"
|
||||
|
||||
|
||||
10
packages/medusa/src/services/__mocks__/middleware.js
Normal file
10
packages/medusa/src/services/__mocks__/middleware.js
Normal file
@@ -0,0 +1,10 @@
|
||||
export const MiddlewareServiceMock = {
|
||||
usePostAuthentication: jest.fn(),
|
||||
usePreAuthentication: jest.fn(),
|
||||
}
|
||||
|
||||
const mock = jest.fn().mockImplementation(() => {
|
||||
return MiddlewareServiceMock
|
||||
})
|
||||
|
||||
export default mock
|
||||
81
packages/medusa/src/services/__tests__/middleware.js
Normal file
81
packages/medusa/src/services/__tests__/middleware.js
Normal file
@@ -0,0 +1,81 @@
|
||||
import mongoose from "mongoose"
|
||||
import { IdMap } from "medusa-test-utils"
|
||||
import MiddlewareService from "../middleware"
|
||||
|
||||
describe("MiddlewareService", () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
describe("addPostAuthentication", () => {
|
||||
const middlewareService = new MiddlewareService()
|
||||
|
||||
it("adds middleware function", () => {
|
||||
middlewareService.addPostAuthentication(() => "post", {})
|
||||
expect(middlewareService.postAuthentication_.length).toEqual(1)
|
||||
})
|
||||
|
||||
it("fails when no function", () => {
|
||||
expect(() => middlewareService.addPostAuthentication("post", {})).toThrow(
|
||||
"Middleware must be a function"
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("addPreAuthentication", () => {
|
||||
const middlewareService = new MiddlewareService()
|
||||
|
||||
it("adds middleware function", () => {
|
||||
middlewareService.addPreAuthentication(() => "pre", {})
|
||||
expect(middlewareService.preAuthentication_.length).toEqual(1)
|
||||
})
|
||||
|
||||
it("fails when no function", () => {
|
||||
expect(() => middlewareService.addPreAuthentication("pre", {})).toThrow(
|
||||
"Middleware must be a function"
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("usePostAuthentication", () => {
|
||||
const middlewareService = new MiddlewareService()
|
||||
|
||||
it("calls middleware", () => {
|
||||
// This doesn't reflect how middleware works but does suffice in our
|
||||
// testing situation
|
||||
const mid = args => args
|
||||
|
||||
middlewareService.addPostAuthentication(mid, { data: "yes" })
|
||||
|
||||
const app = {
|
||||
use: jest.fn(),
|
||||
}
|
||||
|
||||
middlewareService.usePostAuthentication(app)
|
||||
|
||||
expect(app.use).toHaveBeenCalledTimes(1)
|
||||
expect(app.use).toHaveBeenCalledWith({ data: "yes" })
|
||||
})
|
||||
})
|
||||
|
||||
describe("usePreAuthentication", () => {
|
||||
const middlewareService = new MiddlewareService()
|
||||
|
||||
it("calls middleware", () => {
|
||||
// This doesn't reflect how middleware works but does suffice in our
|
||||
// testing situation
|
||||
const mid = args => args
|
||||
|
||||
middlewareService.addPreAuthentication(mid, { data: "yes" })
|
||||
|
||||
const app = {
|
||||
use: jest.fn(),
|
||||
}
|
||||
|
||||
middlewareService.usePreAuthentication(app)
|
||||
|
||||
expect(app.use).toHaveBeenCalledTimes(1)
|
||||
expect(app.use).toHaveBeenCalledWith({ data: "yes" })
|
||||
})
|
||||
})
|
||||
})
|
||||
80
packages/medusa/src/services/middleware.js
Normal file
80
packages/medusa/src/services/middleware.js
Normal file
@@ -0,0 +1,80 @@
|
||||
import { MedusaError } from "medusa-core-utils"
|
||||
|
||||
/**
|
||||
* Orchestrates dynamic middleware registered through the Medusa Middleware API
|
||||
*/
|
||||
class MiddlewareService {
|
||||
constructor(container) {
|
||||
this.postAuthentication_ = []
|
||||
this.preAuthentication_ = []
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a middleware function, throws if fn is not of type function.
|
||||
* @param {function} fn - the middleware function to validate.
|
||||
*/
|
||||
validateMiddleware_(fn) {
|
||||
if (typeof fn !== "function") {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.NOT_ALLOWED,
|
||||
"Middleware must be a function"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a middleware function to be called after authentication is completed.
|
||||
* @param {function} middleware - the middleware function. Should return a
|
||||
* middleware function.
|
||||
* @param {object} options - the arguments that will be passed to the
|
||||
* middleware
|
||||
* @return {void}
|
||||
*/
|
||||
addPostAuthentication(middleware, options) {
|
||||
this.validateMiddleware_(middleware)
|
||||
this.postAuthentication_.push({
|
||||
middleware,
|
||||
options: options || {},
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a middleware function to be called before authentication is completed.
|
||||
* @param {function} middleware - the middleware function. Should return a
|
||||
* middleware function.
|
||||
* @param {object} options - the arguments that will be passed to the
|
||||
* middleware
|
||||
* @return {void}
|
||||
*/
|
||||
addPreAuthentication(middleware, options) {
|
||||
this.validateMiddleware_(middleware)
|
||||
this.preAuthentication_.push({
|
||||
middleware,
|
||||
options: options || {},
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds post authentication middleware to an express app.
|
||||
* @param {ExpressApp} app - the express app to add the middleware to
|
||||
* @return {void}
|
||||
*/
|
||||
usePostAuthentication(app) {
|
||||
for (const object of this.postAuthentication_) {
|
||||
app.use(object.middleware(object.options))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds pre authentication middleware to an express app.
|
||||
* @param {ExpressApp} app - the express app to add the middleware to
|
||||
* @return {void}
|
||||
*/
|
||||
usePreAuthentication(app) {
|
||||
for (const object of this.preAuthentication_) {
|
||||
app.use(object.middleware(object.options))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default MiddlewareService
|
||||
File diff suppressed because it is too large
Load Diff
184
yarn.lock
184
yarn.lock
@@ -2,6 +2,157 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@babel/code-frame@^7.8.3":
|
||||
version "7.8.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e"
|
||||
integrity sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==
|
||||
dependencies:
|
||||
"@babel/highlight" "^7.8.3"
|
||||
|
||||
"@babel/generator@^7.9.5":
|
||||
version "7.9.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.9.5.tgz#27f0917741acc41e6eaaced6d68f96c3fa9afaf9"
|
||||
integrity sha512-GbNIxVB3ZJe3tLeDm1HSn2AhuD/mVcyLDpgtLXa5tplmWrJdF/elxB56XNqCuD6szyNkDi6wuoKXln3QeBmCHQ==
|
||||
dependencies:
|
||||
"@babel/types" "^7.9.5"
|
||||
jsesc "^2.5.1"
|
||||
lodash "^4.17.13"
|
||||
source-map "^0.5.0"
|
||||
|
||||
"@babel/helper-annotate-as-pure@^7.8.3":
|
||||
version "7.8.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.8.3.tgz#60bc0bc657f63a0924ff9a4b4a0b24a13cf4deee"
|
||||
integrity sha512-6o+mJrZBxOoEX77Ezv9zwW7WV8DdluouRKNY/IR5u/YTMuKHgugHOzYWlYvYLpLA9nPsQCAAASpCIbjI9Mv+Uw==
|
||||
dependencies:
|
||||
"@babel/types" "^7.8.3"
|
||||
|
||||
"@babel/helper-define-map@^7.8.3":
|
||||
version "7.8.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.8.3.tgz#a0655cad5451c3760b726eba875f1cd8faa02c15"
|
||||
integrity sha512-PoeBYtxoZGtct3md6xZOCWPcKuMuk3IHhgxsRRNtnNShebf4C8YonTSblsK4tvDbm+eJAw2HAPOfCr+Q/YRG/g==
|
||||
dependencies:
|
||||
"@babel/helper-function-name" "^7.8.3"
|
||||
"@babel/types" "^7.8.3"
|
||||
lodash "^4.17.13"
|
||||
|
||||
"@babel/helper-function-name@^7.8.3", "@babel/helper-function-name@^7.9.5":
|
||||
version "7.9.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz#2b53820d35275120e1874a82e5aabe1376920a5c"
|
||||
integrity sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==
|
||||
dependencies:
|
||||
"@babel/helper-get-function-arity" "^7.8.3"
|
||||
"@babel/template" "^7.8.3"
|
||||
"@babel/types" "^7.9.5"
|
||||
|
||||
"@babel/helper-get-function-arity@^7.8.3":
|
||||
version "7.8.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz#b894b947bd004381ce63ea1db9f08547e920abd5"
|
||||
integrity sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==
|
||||
dependencies:
|
||||
"@babel/types" "^7.8.3"
|
||||
|
||||
"@babel/helper-member-expression-to-functions@^7.8.3":
|
||||
version "7.8.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz#659b710498ea6c1d9907e0c73f206eee7dadc24c"
|
||||
integrity sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA==
|
||||
dependencies:
|
||||
"@babel/types" "^7.8.3"
|
||||
|
||||
"@babel/helper-optimise-call-expression@^7.8.3":
|
||||
version "7.8.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz#7ed071813d09c75298ef4f208956006b6111ecb9"
|
||||
integrity sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ==
|
||||
dependencies:
|
||||
"@babel/types" "^7.8.3"
|
||||
|
||||
"@babel/helper-plugin-utils@^7.8.3":
|
||||
version "7.8.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz#9ea293be19babc0f52ff8ca88b34c3611b208670"
|
||||
integrity sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==
|
||||
|
||||
"@babel/helper-replace-supers@^7.8.6":
|
||||
version "7.8.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.8.6.tgz#5ada744fd5ad73203bf1d67459a27dcba67effc8"
|
||||
integrity sha512-PeMArdA4Sv/Wf4zXwBKPqVj7n9UF/xg6slNRtZW84FM7JpE1CbG8B612FyM4cxrf4fMAMGO0kR7voy1ForHHFA==
|
||||
dependencies:
|
||||
"@babel/helper-member-expression-to-functions" "^7.8.3"
|
||||
"@babel/helper-optimise-call-expression" "^7.8.3"
|
||||
"@babel/traverse" "^7.8.6"
|
||||
"@babel/types" "^7.8.6"
|
||||
|
||||
"@babel/helper-split-export-declaration@^7.8.3":
|
||||
version "7.8.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz#31a9f30070f91368a7182cf05f831781065fc7a9"
|
||||
integrity sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==
|
||||
dependencies:
|
||||
"@babel/types" "^7.8.3"
|
||||
|
||||
"@babel/helper-validator-identifier@^7.9.0", "@babel/helper-validator-identifier@^7.9.5":
|
||||
version "7.9.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz#90977a8e6fbf6b431a7dc31752eee233bf052d80"
|
||||
integrity sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==
|
||||
|
||||
"@babel/highlight@^7.8.3":
|
||||
version "7.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.9.0.tgz#4e9b45ccb82b79607271b2979ad82c7b68163079"
|
||||
integrity sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==
|
||||
dependencies:
|
||||
"@babel/helper-validator-identifier" "^7.9.0"
|
||||
chalk "^2.0.0"
|
||||
js-tokens "^4.0.0"
|
||||
|
||||
"@babel/parser@^7.8.6", "@babel/parser@^7.9.0":
|
||||
version "7.9.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.9.4.tgz#68a35e6b0319bbc014465be43828300113f2f2e8"
|
||||
integrity sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA==
|
||||
|
||||
"@babel/plugin-transform-classes@^7.9.5":
|
||||
version "7.9.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.9.5.tgz#800597ddb8aefc2c293ed27459c1fcc935a26c2c"
|
||||
integrity sha512-x2kZoIuLC//O5iA7PEvecB105o7TLzZo8ofBVhP79N+DO3jaX+KYfww9TQcfBEZD0nikNyYcGB1IKtRq36rdmg==
|
||||
dependencies:
|
||||
"@babel/helper-annotate-as-pure" "^7.8.3"
|
||||
"@babel/helper-define-map" "^7.8.3"
|
||||
"@babel/helper-function-name" "^7.9.5"
|
||||
"@babel/helper-optimise-call-expression" "^7.8.3"
|
||||
"@babel/helper-plugin-utils" "^7.8.3"
|
||||
"@babel/helper-replace-supers" "^7.8.6"
|
||||
"@babel/helper-split-export-declaration" "^7.8.3"
|
||||
globals "^11.1.0"
|
||||
|
||||
"@babel/template@^7.8.3":
|
||||
version "7.8.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.6.tgz#86b22af15f828dfb086474f964dcc3e39c43ce2b"
|
||||
integrity sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.8.3"
|
||||
"@babel/parser" "^7.8.6"
|
||||
"@babel/types" "^7.8.6"
|
||||
|
||||
"@babel/traverse@^7.8.6":
|
||||
version "7.9.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.9.5.tgz#6e7c56b44e2ac7011a948c21e283ddd9d9db97a2"
|
||||
integrity sha512-c4gH3jsvSuGUezlP6rzSJ6jf8fYjLj3hsMZRx/nX0h+fmHN0w+ekubRrHPqnMec0meycA2nwCsJ7dC8IPem2FQ==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.8.3"
|
||||
"@babel/generator" "^7.9.5"
|
||||
"@babel/helper-function-name" "^7.9.5"
|
||||
"@babel/helper-split-export-declaration" "^7.8.3"
|
||||
"@babel/parser" "^7.9.0"
|
||||
"@babel/types" "^7.9.5"
|
||||
debug "^4.1.0"
|
||||
globals "^11.1.0"
|
||||
lodash "^4.17.13"
|
||||
|
||||
"@babel/types@^7.8.3", "@babel/types@^7.8.6", "@babel/types@^7.9.5":
|
||||
version "7.9.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.9.5.tgz#89231f82915a8a566a703b3b20133f73da6b9444"
|
||||
integrity sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==
|
||||
dependencies:
|
||||
"@babel/helper-validator-identifier" "^7.9.5"
|
||||
lodash "^4.17.13"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@evocateur/libnpmaccess@^3.1.2":
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@evocateur/libnpmaccess/-/libnpmaccess-3.1.2.tgz#ecf7f6ce6b004e9f942b098d92200be4a4b1c845"
|
||||
@@ -1250,7 +1401,7 @@ caseless@~0.12.0:
|
||||
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
|
||||
integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=
|
||||
|
||||
chalk@^2.3.1, chalk@^2.4.2:
|
||||
chalk@^2.0.0, chalk@^2.3.1, chalk@^2.4.2:
|
||||
version "2.4.2"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
|
||||
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
|
||||
@@ -1593,6 +1744,13 @@ debug@^3.1.0:
|
||||
dependencies:
|
||||
ms "^2.1.1"
|
||||
|
||||
debug@^4.1.0:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
|
||||
integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==
|
||||
dependencies:
|
||||
ms "^2.1.1"
|
||||
|
||||
debuglog@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492"
|
||||
@@ -2191,6 +2349,11 @@ glob@^7.1.1, glob@^7.1.3, glob@^7.1.4:
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
globals@^11.1.0:
|
||||
version "11.12.0"
|
||||
resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
|
||||
integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
|
||||
|
||||
globby@^9.2.0:
|
||||
version "9.2.0"
|
||||
resolved "https://registry.yarnpkg.com/globby/-/globby-9.2.0.tgz#fd029a706c703d29bdd170f4b6db3a3f7a7cb63d"
|
||||
@@ -2691,6 +2854,11 @@ isstream@~0.1.2:
|
||||
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
|
||||
integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=
|
||||
|
||||
js-tokens@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
|
||||
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
|
||||
|
||||
js-yaml@^3.13.1:
|
||||
version "3.13.1"
|
||||
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
|
||||
@@ -2704,6 +2872,11 @@ jsbn@~0.1.0:
|
||||
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
|
||||
integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM=
|
||||
|
||||
jsesc@^2.5.1:
|
||||
version "2.5.2"
|
||||
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
|
||||
integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
|
||||
|
||||
json-parse-better-errors@^1.0.0, json-parse-better-errors@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9"
|
||||
@@ -2892,7 +3065,7 @@ lodash.uniq@^4.5.0:
|
||||
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
|
||||
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
|
||||
|
||||
lodash@^4.17.12, lodash@^4.17.15, lodash@^4.2.1:
|
||||
lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.15, lodash@^4.2.1:
|
||||
version "4.17.15"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
|
||||
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
|
||||
@@ -4195,7 +4368,7 @@ source-map-url@^0.4.0:
|
||||
resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3"
|
||||
integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=
|
||||
|
||||
source-map@^0.5.6:
|
||||
source-map@^0.5.0, source-map@^0.5.6:
|
||||
version "0.5.7"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
|
||||
integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
|
||||
@@ -4498,6 +4671,11 @@ tmp@^0.0.33:
|
||||
dependencies:
|
||||
os-tmpdir "~1.0.2"
|
||||
|
||||
to-fast-properties@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
|
||||
integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=
|
||||
|
||||
to-object-path@^0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af"
|
||||
|
||||
Reference in New Issue
Block a user