Adds an image connector; introduces file service

This commit is contained in:
Sebastian Rindom
2020-07-07 14:36:48 +02:00
parent 8c5fa44e5f
commit 716415263d
16 changed files with 314 additions and 9 deletions

View File

@@ -0,0 +1,13 @@
{
"plugins": [
"@babel/plugin-proposal-class-properties",
"@babel/plugin-transform-instanceof",
"@babel/plugin-transform-classes"
],
"presets": ["@babel/preset-env"],
"env": {
"test": {
"plugins": ["@babel/plugin-transform-runtime"]
}
}
}

View File

@@ -0,0 +1,9 @@
{
"plugins": ["prettier"],
"extends": ["prettier"],
"rules": {
"prettier/prettier": "error",
"semi": "error",
"no-unused-expressions": "true"
}
}

16
packages/medusa-file-spaces/.gitignore vendored Normal file
View File

@@ -0,0 +1,16 @@
/lib
node_modules
.DS_store
.env*
/*.js
!index.js
yarn.lock
/dist
/api
/services
/models
/subscribers
/__mocks__

View File

@@ -0,0 +1,9 @@
/lib
node_modules
.DS_store
.env*
/*.js
!index.js
yarn.lock

View File

@@ -0,0 +1,7 @@
{
"endOfLine": "lf",
"semi": false,
"singleQuote": false,
"tabWidth": 2,
"trailingComma": "es5"
}

View File

@@ -0,0 +1 @@
// noop

View File

@@ -0,0 +1,46 @@
{
"name": "medusa-file-spaces",
"version": "0.3.0",
"description": "Digital Ocean Spaces file connector for Medusa",
"main": "index.js",
"repository": {
"type": "git",
"url": "https://github.com/medusajs/medusa",
"directory": "packages/medusa-file-spaces"
},
"author": "Sebastian Rindom",
"license": "AGPL-3.0-or-later",
"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.9.6",
"client-sessions": "^0.8.0",
"cross-env": "^5.2.1",
"eslint": "^6.8.0",
"jest": "^25.5.2",
"medusa-test-utils": "^0.3.0"
},
"scripts": {
"build": "babel src -d .",
"prepare": "cross-env NODE_ENV=production npm run build",
"watch": "babel -w src --out-dir . --ignore **/__tests__",
"test": "jest"
},
"dependencies": {
"@babel/plugin-transform-classes": "^7.9.5",
"aws-sdk": "^2.710.0",
"body-parser": "^1.19.0",
"express": "^4.17.1",
"medusa-core-utils": "^0.3.0",
"medusa-interfaces": "^0.3.0",
"medusa-test-utils": "^0.3.0",
"stripe": "^8.50.0"
},
"gitHead": "35e0930650d5f4aedf2610749cd131ae8b7e17cc"
}

View File

@@ -0,0 +1,51 @@
import fs from "fs"
import aws from "aws-sdk"
import { FileService } from "medusa-interfaces"
class DigitalOceanService extends FileService {
constructor({}, options) {
super()
this.bucket_ = options.bucket
this.spacesUrl_ = options.spaces_url
this.accessKeyId_ = options.access_key_id
this.secretAccessKey_ = options.secret_access_key
this.region_ = options.region
this.endpoint_ = options.endpoint
}
upload(file) {
aws.config.setPromisesDependency();
aws.config.update({
accessKeyId: this.accessKeyId_,
secretAccessKey: this.secretAccessKey_,
region: this.region_,
endpoint: this.endpoint_,
});
const s3 = new aws.S3();
var params = {
ACL: 'public-read',
Bucket: this.bucket_,
Body: fs.createReadStream(file.path),
Key: `${file.originalname}`
}
return new Promise((resolve, reject) => {
s3.upload(params, (err, data) => {
if (err) {
reject(err)
return
}
resolve({ url: data.Location })
})
})
}
delete(file) {
console.log(file)
}
}
export default DigitalOceanService

View File

@@ -0,0 +1,21 @@
import BaseService from "./base-service"
/**
* Interface for file connectors
* @interface
*/
class BaseFileService extends BaseService {
constructor() {
super()
}
upload() {
throw Error("upload must be overridden by the child class")
}
delete() {
throw Error("delete must be overridden by the child class")
}
}
export default BaseFileService

View File

@@ -2,3 +2,4 @@ export { default as BaseService } from "./base-service"
export { default as BaseModel } from "./base-model"
export { default as PaymentService } from "./payment-service"
export { default as FulfillmentService } from "./fulfillment-service"
export { default as FileService } from "./file-service"

View File

@@ -38,9 +38,6 @@
"serve": "node dist/app.js",
"test": "jest"
},
"peerDependencies": {
"medusa-interfaces": "^0.3.0"
},
"peerDependencies": {
"mongoose": "5.x"
},
@@ -65,6 +62,7 @@
"medusa-interfaces": "^0.1.27",
"medusa-test-utils": "^0.3.0",
"morgan": "^1.9.1",
"multer": "^1.4.2",
"passport": "^0.4.0",
"passport-http-bearer": "^1.0.1",
"passport-jwt": "^4.0.0",
@@ -72,4 +70,4 @@
"winston": "^3.2.1"
},
"gitHead": "35e0930650d5f4aedf2610749cd131ae8b7e17cc"
}
}

View File

@@ -11,6 +11,7 @@ import shippingProfileRoutes from "./shipping-profiles"
import discountRoutes from "./discounts"
import orderRoutes from "./orders"
import storeRoutes from "./store"
import uploadRoutes from "./uploads"
const route = Router()
@@ -46,6 +47,7 @@ export default (app, container, config) => {
discountRoutes(route)
orderRoutes(route)
storeRoutes(route)
uploadRoutes(route)
return app
}

View File

@@ -0,0 +1,24 @@
import fs from "fs"
export default async (req, res) => {
try {
const fileService = req.scope.resolve("fileService")
console.log(fileService)
const result = await Promise.all(
req.files.map(async f => {
console.log(f)
return fileService.upload(f).then(result => {
fs.unlinkSync(f.path)
return result
})
})
)
res.status(200).json({ uploads: result })
} catch (err) {
console.log(err)
throw err
}
}

View File

@@ -0,0 +1,19 @@
import { Router } from "express"
import multer from "multer"
import middlewares from "../../../middlewares"
const route = Router()
const upload = multer({ dest: "uploads/" })
export default app => {
app.use("/uploads", route)
route.post(
"/",
upload.array("files"),
middlewares.wrap(require("./create-upload").default)
)
return app
}

View File

@@ -4,6 +4,7 @@ import {
BaseService,
PaymentService,
FulfillmentService,
FileService,
} from "medusa-interfaces"
import { getConfigFile, createRequireFromPath } from "medusa-core-utils"
import _ from "lodash"
@@ -147,6 +148,13 @@ function registerServices(pluginDetails, container) {
[name]: asFunction(cradle => new loaded(cradle, pluginDetails.options)),
[`fp_${loaded.identifier}`]: aliasTo(name),
})
} else if (loaded.prototype instanceof FileService) {
// 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({
[name]: asFunction(cradle => new loaded(cradle, pluginDetails.options)),
[`fileService`]: aliasTo(name),
})
} else {
container.register({
[name]: asFunction(cradle => new loaded(cradle, pluginDetails.options)),

View File

@@ -1423,6 +1423,11 @@ anymatch@^3.0.3, anymatch@~3.1.1:
normalize-path "^3.0.0"
picomatch "^2.0.4"
append-field@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/append-field/-/append-field-1.0.0.tgz#1e3440e915f0b1203d23748e78edd7b9b5b43e56"
integrity sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY=
aproba@^1.0.3:
version "1.2.0"
resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
@@ -1774,6 +1779,14 @@ bull@^3.12.1:
util.promisify "^1.0.0"
uuid "^3.3.3"
busboy@^0.2.11:
version "0.2.14"
resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.2.14.tgz#6c2a622efcf47c57bbbe1e2a9c37ad36c7925453"
integrity sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=
dependencies:
dicer "0.2.5"
readable-stream "1.1.x"
bytes@3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6"
@@ -2071,6 +2084,16 @@ concat-map@0.0.1:
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
concat-stream@^1.5.2:
version "1.6.2"
resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34"
integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==
dependencies:
buffer-from "^1.0.0"
inherits "^2.0.3"
readable-stream "^2.2.2"
typedarray "^0.0.6"
configstore@^3.0.0:
version "3.1.2"
resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.2.tgz#c6f25defaeef26df12dd33414b001fe81a543f8f"
@@ -2399,6 +2422,14 @@ diagnostics@^1.1.1:
enabled "1.0.x"
kuler "1.0.x"
dicer@0.2.5:
version "0.2.5"
resolved "https://registry.yarnpkg.com/dicer/-/dicer-0.2.5.tgz#5996c086bb33218c812c090bddc09cd12facb70f"
integrity sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=
dependencies:
readable-stream "1.1.x"
streamsearch "0.1.2"
diff-sequences@^25.2.6:
version "25.2.6"
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-25.2.6.tgz#5f467c00edd35352b7bca46d7927d60e687a76dd"
@@ -3389,7 +3420,7 @@ inflight@^1.0.4:
once "^1.3.0"
wrappy "1"
inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@~2.0.3:
inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3:
version "2.0.4"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
@@ -3712,6 +3743,11 @@ is-wsl@^2.1.1:
resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.1.1.tgz#4a1c152d429df3d441669498e2486d3596ebaf1d"
integrity sha512-umZHcSrwlDHo2TGMXv0DZ8dIUGunZ2Iv68YZnrmCiBPkZ4aaOhtv7pXJKeki9k3qJ3RJr0cDyitcl5wEH3AYog==
isarray@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=
isarray@1.0.0, isarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
@@ -4747,6 +4783,20 @@ ms@2.1.2, ms@^2.1.1:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
multer@^1.4.2:
version "1.4.2"
resolved "https://registry.yarnpkg.com/multer/-/multer-1.4.2.tgz#2f1f4d12dbaeeba74cb37e623f234bf4d3d2057a"
integrity sha512-xY8pX7V+ybyUpbYMxtjM9KAiD9ixtg5/JkeKUTD6xilfDv0vzzOFcCp4Ljb1UU3tSOM3VTZtKo63OmzOrGi3Cg==
dependencies:
append-field "^1.0.0"
busboy "^0.2.11"
concat-stream "^1.5.2"
mkdirp "^0.5.1"
object-assign "^4.1.1"
on-finished "^2.3.0"
type-is "^1.6.4"
xtend "^4.0.0"
mute-stream@0.0.8:
version "0.0.8"
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d"
@@ -4978,7 +5028,7 @@ oauth-sign@~0.9.0:
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
object-assign@^4, object-assign@^4.1.0:
object-assign@^4, object-assign@^4.1.0, object-assign@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
@@ -5034,7 +5084,7 @@ object.pick@^1.3.0:
dependencies:
isobject "^3.0.1"
on-finished@~2.3.0:
on-finished@^2.3.0, on-finished@~2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947"
integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=
@@ -5500,6 +5550,16 @@ read-pkg@^5.2.0:
parse-json "^5.0.0"
type-fest "^0.6.0"
readable-stream@1.1.x:
version "1.1.14"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9"
integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk=
dependencies:
core-util-is "~1.0.0"
inherits "~2.0.1"
isarray "0.0.1"
string_decoder "~0.10.x"
readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.3.6:
version "2.3.6"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf"
@@ -5513,7 +5573,7 @@ readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.3.6:
string_decoder "~1.1.1"
util-deprecate "~1.0.1"
readable-stream@^2.3.5:
readable-stream@^2.2.2, readable-stream@^2.3.5:
version "2.3.7"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
@@ -6187,6 +6247,11 @@ stealthy-require@^1.1.1:
resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b"
integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=
streamsearch@0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a"
integrity sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=
string-length@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/string-length/-/string-length-3.1.0.tgz#107ef8c23456e187a8abd4a61162ff4ac6e25837"
@@ -6253,6 +6318,11 @@ string_decoder@^1.1.1:
dependencies:
safe-buffer "~5.2.0"
string_decoder@~0.10.x:
version "0.10.31"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=
string_decoder@~1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
@@ -6570,7 +6640,7 @@ type-fest@^0.8.1:
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d"
integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==
type-is@~1.6.17, type-is@~1.6.18:
type-is@^1.6.4, type-is@~1.6.17, type-is@~1.6.18:
version "1.6.18"
resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131"
integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==
@@ -6585,6 +6655,11 @@ typedarray-to-buffer@^3.1.5:
dependencies:
is-typedarray "^1.0.0"
typedarray@^0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
uid-safe@~2.1.5:
version "2.1.5"
resolved "https://registry.yarnpkg.com/uid-safe/-/uid-safe-2.1.5.tgz#2b3d5c7240e8fc2e58f8aa269e5ee49c0857bd3a"
@@ -6943,6 +7018,11 @@ xmlchars@^2.1.1:
resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb"
integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==
xtend@^4.0.0:
version "4.0.2"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
y18n@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b"