feat(medusa-file-s3,medusa-file-minio): Upgrade to TypeScript (#3740)
This commit is contained in:
6
.changeset/chilly-carpets-explode.md
Normal file
6
.changeset/chilly-carpets-explode.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"medusa-file-minio": minor
|
||||
"medusa-file-s3": minor
|
||||
---
|
||||
|
||||
Migrate medusa-file-minio and medusa-file-s3 to typescript.
|
||||
@@ -2,7 +2,10 @@
|
||||
"name": "medusa-file-minio",
|
||||
"version": "1.1.6",
|
||||
"description": "MinIO server file connector for Medusa",
|
||||
"main": "index.js",
|
||||
"main": "dist/index.js",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/medusajs/medusa",
|
||||
@@ -11,32 +14,22 @@
|
||||
"author": "Edin Skeja",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.16.0",
|
||||
"@babel/core": "^7.16.0",
|
||||
"@babel/node": "^7.16.0",
|
||||
"@babel/plugin-proposal-class-properties": "^7.16.0",
|
||||
"@babel/plugin-transform-instanceof": "^7.16.0",
|
||||
"@babel/plugin-transform-runtime": "^7.16.4",
|
||||
"@babel/preset-env": "^7.16.4",
|
||||
"@babel/register": "^7.16.0",
|
||||
"@babel/runtime": "^7.16.3",
|
||||
"client-sessions": "^0.8.0",
|
||||
"@medusajs/medusa": "1.8.0-rc.6",
|
||||
"cross-env": "^5.2.1",
|
||||
"jest": "^25.5.4",
|
||||
"medusa-interfaces": "^1.3.7"
|
||||
"typescript": "^4.9.5"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "babel src --out-dir dist/ --ignore '**/__tests__','**/__mocks__'",
|
||||
"prepare": "cross-env NODE_ENV=production yarn run build",
|
||||
"watch": "babel -w src --out-dir dist/ --ignore '**/__tests__','**/__mocks__'",
|
||||
"test": "jest --passWithNoTests src"
|
||||
"test": "jest --passWithNoTests src",
|
||||
"build": "tsc",
|
||||
"watch": "tsc --watch"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"medusa-interfaces": "1.3.7"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/plugin-transform-classes": "^7.16.0",
|
||||
"aws-sdk": "^2.1043.0",
|
||||
"aws-sdk": "^2.983.0",
|
||||
"body-parser": "^1.19.0",
|
||||
"express": "^4.17.1",
|
||||
"medusa-core-utils": "^1.2.0",
|
||||
|
||||
@@ -1,182 +0,0 @@
|
||||
import stream from "stream"
|
||||
import aws from "aws-sdk"
|
||||
import { parse } from "path"
|
||||
import fs from "fs"
|
||||
import { AbstractFileService } from "@medusajs/medusa"
|
||||
import { MedusaError } from "medusa-core-utils"
|
||||
|
||||
class MinioService extends AbstractFileService {
|
||||
constructor({}, options) {
|
||||
super({}, options)
|
||||
|
||||
this.bucket_ = options.bucket
|
||||
this.accessKeyId_ = options.access_key_id
|
||||
this.secretAccessKey_ = options.secret_access_key
|
||||
this.private_bucket_ = options.private_bucket
|
||||
this.private_access_key_id_ =
|
||||
options.private_access_key_id ?? this.accessKeyId_
|
||||
this.private_secret_access_key_ =
|
||||
options.private_secret_access_key ?? this.secretAccessKey_
|
||||
this.endpoint_ = options.endpoint
|
||||
this.s3ForcePathStyle_ = true
|
||||
this.signatureVersion_ = "v4"
|
||||
this.downloadUrlDuration = options.download_url_duration ?? 60 // 60 seconds
|
||||
}
|
||||
|
||||
upload(file) {
|
||||
this.updateAwsConfig_()
|
||||
|
||||
return this.uploadFile(file)
|
||||
}
|
||||
|
||||
uploadProtected(file) {
|
||||
this.validatePrivateBucketConfiguration_(true)
|
||||
this.updateAwsConfig_(true)
|
||||
|
||||
return this.uploadFile(file, { isProtected: true })
|
||||
}
|
||||
|
||||
uploadFile(file, options = { isProtected: false }) {
|
||||
const parsedFilename = parse(file.originalname)
|
||||
const fileKey = `${parsedFilename.name}-${Date.now()}${parsedFilename.ext}`
|
||||
|
||||
const s3 = new aws.S3()
|
||||
const params = {
|
||||
ACL: options.isProtected ? "private" : "public-read",
|
||||
Bucket: options.isProtected ? this.private_bucket_ : this.bucket_,
|
||||
Body: fs.createReadStream(file.path),
|
||||
Key: fileKey,
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
s3.upload(params, (err, data) => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
return
|
||||
}
|
||||
|
||||
resolve({ url: data.Location, key: data.Key })
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
async delete(file) {
|
||||
this.updateAwsConfig_()
|
||||
|
||||
const s3 = new aws.S3()
|
||||
const params = {
|
||||
Bucket: this.bucket_,
|
||||
Key: `${file.fileKey}`,
|
||||
}
|
||||
|
||||
return await Promise.all([
|
||||
new Promise((resolve, reject) =>
|
||||
s3.deleteObject({ ...params, Bucket: this.bucket_ }, (err, data) => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
return
|
||||
}
|
||||
resolve(data)
|
||||
})
|
||||
),
|
||||
new Promise((resolve, reject) =>
|
||||
s3.deleteObject(
|
||||
{ ...params, Bucket: this.private_bucket_ },
|
||||
(err, data) => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
return
|
||||
}
|
||||
resolve(data)
|
||||
}
|
||||
)
|
||||
),
|
||||
])
|
||||
}
|
||||
|
||||
async getUploadStreamDescriptor({ usePrivateBucket = true, ...fileData }) {
|
||||
this.validatePrivateBucketConfiguration_(usePrivateBucket)
|
||||
this.updateAwsConfig_(usePrivateBucket)
|
||||
|
||||
const pass = new stream.PassThrough()
|
||||
|
||||
const fileKey = `${fileData.name}.${fileData.ext}`
|
||||
const params = {
|
||||
Bucket: usePrivateBucket ? this.private_bucket_ : this.bucket_,
|
||||
Body: pass,
|
||||
Key: fileKey,
|
||||
}
|
||||
|
||||
const s3 = new aws.S3()
|
||||
return {
|
||||
writeStream: pass,
|
||||
promise: s3.upload(params).promise(),
|
||||
url: `${this.spacesUrl_}/${fileKey}`,
|
||||
fileKey,
|
||||
}
|
||||
}
|
||||
|
||||
async getDownloadStream({ usePrivateBucket = true, ...fileData }) {
|
||||
this.validatePrivateBucketConfiguration_(usePrivateBucket)
|
||||
this.updateAwsConfig_(usePrivateBucket)
|
||||
|
||||
const s3 = new aws.S3()
|
||||
|
||||
const params = {
|
||||
Bucket: usePrivateBucket ? this.private_bucket_ : this.bucket_,
|
||||
Key: `${fileData.fileKey}`,
|
||||
}
|
||||
|
||||
return s3.getObject(params).createReadStream()
|
||||
}
|
||||
|
||||
async getPresignedDownloadUrl({ usePrivateBucket = true, ...fileData }) {
|
||||
this.validatePrivateBucketConfiguration_(usePrivateBucket)
|
||||
this.updateAwsConfig_(usePrivateBucket, {
|
||||
signatureVersion: "v4",
|
||||
})
|
||||
|
||||
const s3 = new aws.S3()
|
||||
|
||||
const params = {
|
||||
Bucket: usePrivateBucket ? this.private_bucket_ : this.bucket_,
|
||||
Key: `${fileData.fileKey}`,
|
||||
Expires: this.downloadUrlDuration,
|
||||
}
|
||||
|
||||
return await s3.getSignedUrlPromise("getObject", params)
|
||||
}
|
||||
|
||||
validatePrivateBucketConfiguration_(usePrivateBucket) {
|
||||
if (
|
||||
usePrivateBucket &&
|
||||
(!this.private_access_key_id_ || !this.private_bucket_)
|
||||
) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.UNEXPECTED_STATE,
|
||||
"Private bucket is not configured"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
updateAwsConfig_(usePrivateBucket = false, additionalConfiguration = {}) {
|
||||
aws.config.setPromisesDependency(null)
|
||||
aws.config.update(
|
||||
{
|
||||
accessKeyId: usePrivateBucket
|
||||
? this.private_access_key_id_
|
||||
: this.accessKeyId_,
|
||||
secretAccessKey: usePrivateBucket
|
||||
? this.private_secret_access_key_
|
||||
: this.secretAccessKey_,
|
||||
endpoint: this.endpoint_,
|
||||
s3ForcePathStyle: this.s3ForcePathStyle_,
|
||||
signatureVersion: this.signatureVersion_,
|
||||
...additionalConfiguration,
|
||||
},
|
||||
true
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default MinioService
|
||||
212
packages/medusa-file-minio/src/services/minio.ts
Normal file
212
packages/medusa-file-minio/src/services/minio.ts
Normal file
@@ -0,0 +1,212 @@
|
||||
import stream from "stream"
|
||||
import aws from "aws-sdk"
|
||||
import { parse } from "path"
|
||||
import fs from "fs"
|
||||
import {
|
||||
AbstractFileService,
|
||||
DeleteFileType,
|
||||
FileServiceUploadResult,
|
||||
GetUploadedFileType,
|
||||
IFileService,
|
||||
UploadStreamDescriptorType,
|
||||
} from "@medusajs/medusa"
|
||||
import { MedusaError } from "medusa-core-utils"
|
||||
import { ClientConfiguration, PutObjectRequest } from "aws-sdk/clients/s3"
|
||||
|
||||
class MinioService extends AbstractFileService implements IFileService {
|
||||
protected bucket_: string
|
||||
protected accessKeyId_: string
|
||||
protected secretAccessKey_: string
|
||||
protected private_bucket_: string
|
||||
protected private_access_key_id_: string
|
||||
protected private_secret_access_key_: string
|
||||
protected endpoint_: string
|
||||
protected s3ForcePathStyle_: boolean
|
||||
protected signatureVersion_: string
|
||||
protected downloadUrlDuration: string | number
|
||||
|
||||
constructor({}, options) {
|
||||
super({}, options)
|
||||
|
||||
this.bucket_ = options.bucket
|
||||
this.accessKeyId_ = options.access_key_id
|
||||
this.secretAccessKey_ = options.secret_access_key
|
||||
this.private_bucket_ = options.private_bucket
|
||||
this.private_access_key_id_ =
|
||||
options.private_access_key_id ?? this.accessKeyId_
|
||||
this.private_secret_access_key_ =
|
||||
options.private_secret_access_key ?? this.secretAccessKey_
|
||||
this.endpoint_ = options.endpoint
|
||||
this.s3ForcePathStyle_ = true
|
||||
this.signatureVersion_ = "v4"
|
||||
this.downloadUrlDuration = options.download_url_duration ?? 60 // 60 seconds
|
||||
}
|
||||
|
||||
protected buildUrl(bucket: string, key: string) {
|
||||
return `${this.endpoint_}/${bucket}/${key}`
|
||||
}
|
||||
|
||||
async upload(file: Express.Multer.File): Promise<FileServiceUploadResult> {
|
||||
return await this.uploadFile(file)
|
||||
}
|
||||
|
||||
async uploadProtected(
|
||||
file: Express.Multer.File
|
||||
): Promise<FileServiceUploadResult> {
|
||||
this.validatePrivateBucketConfiguration_(true)
|
||||
|
||||
return await this.uploadFile(file, { isProtected: true })
|
||||
}
|
||||
|
||||
protected async uploadFile(
|
||||
file: Express.Multer.File,
|
||||
options: { isProtected: boolean } = { isProtected: false }
|
||||
) {
|
||||
const parsedFilename = parse(file.originalname)
|
||||
const fileKey = `${parsedFilename.name}-${Date.now()}${parsedFilename.ext}`
|
||||
|
||||
const client = this.getClient(options.isProtected)
|
||||
|
||||
const params = {
|
||||
ACL: options.isProtected ? "private" : "public-read",
|
||||
Bucket: options.isProtected ? this.private_bucket_ : this.bucket_,
|
||||
Body: fs.createReadStream(file.path),
|
||||
Key: fileKey,
|
||||
ContentType: file.mimetype,
|
||||
}
|
||||
|
||||
const result = await client.upload(params).promise()
|
||||
|
||||
return { url: result.Location, key: result.Key }
|
||||
}
|
||||
|
||||
async delete(file: DeleteFileType): Promise<void> {
|
||||
const privateClient = this.getClient(false)
|
||||
const publicClient = this.getClient(true)
|
||||
|
||||
const params = {
|
||||
Bucket: this.bucket_,
|
||||
Key: `${file.fileKey}`,
|
||||
}
|
||||
|
||||
await Promise.all([
|
||||
new Promise((resolve, reject) =>
|
||||
publicClient.deleteObject(
|
||||
{ ...params, Bucket: this.bucket_ },
|
||||
(err, data) => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
return
|
||||
}
|
||||
resolve(data)
|
||||
}
|
||||
)
|
||||
),
|
||||
new Promise((resolve, reject) =>
|
||||
privateClient.deleteObject(
|
||||
{ ...params, Bucket: this.private_bucket_ },
|
||||
(err, data) => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
return
|
||||
}
|
||||
resolve(data)
|
||||
}
|
||||
)
|
||||
),
|
||||
])
|
||||
}
|
||||
|
||||
async getUploadStreamDescriptor(
|
||||
fileData: UploadStreamDescriptorType & {
|
||||
usePrivateBucket?: boolean
|
||||
contentType?: string
|
||||
}
|
||||
) {
|
||||
const usePrivateBucket = !!fileData.usePrivateBucket
|
||||
|
||||
this.validatePrivateBucketConfiguration_(usePrivateBucket)
|
||||
|
||||
const client = this.getClient(usePrivateBucket)
|
||||
|
||||
const pass = new stream.PassThrough()
|
||||
|
||||
const fileKey = `${fileData.name}.${fileData.ext}`
|
||||
|
||||
const params: PutObjectRequest = {
|
||||
Bucket: usePrivateBucket ? this.private_bucket_ : this.bucket_,
|
||||
Body: pass,
|
||||
Key: fileKey,
|
||||
ContentType: fileData.contentType,
|
||||
}
|
||||
|
||||
return {
|
||||
writeStream: pass,
|
||||
promise: client.upload(params).promise(),
|
||||
url: this.buildUrl(params.Bucket, fileKey),
|
||||
fileKey,
|
||||
}
|
||||
}
|
||||
|
||||
async getDownloadStream(
|
||||
fileData: GetUploadedFileType & { usePrivateBucket?: boolean }
|
||||
) {
|
||||
const usePrivateBucket = !!fileData.usePrivateBucket
|
||||
this.validatePrivateBucketConfiguration_(usePrivateBucket)
|
||||
const client = this.getClient(usePrivateBucket)
|
||||
|
||||
const params = {
|
||||
Bucket: usePrivateBucket ? this.private_bucket_ : this.bucket_,
|
||||
Key: `${fileData.fileKey}`,
|
||||
}
|
||||
|
||||
return client.getObject(params).createReadStream()
|
||||
}
|
||||
|
||||
async getPresignedDownloadUrl({ usePrivateBucket = true, ...fileData }) {
|
||||
this.validatePrivateBucketConfiguration_(usePrivateBucket)
|
||||
const client = this.getClient(usePrivateBucket, {
|
||||
signatureVersion: "v4",
|
||||
})
|
||||
|
||||
const params = {
|
||||
Bucket: usePrivateBucket ? this.private_bucket_ : this.bucket_,
|
||||
Key: `${fileData.fileKey}`,
|
||||
Expires: this.downloadUrlDuration,
|
||||
}
|
||||
|
||||
return await client.getSignedUrlPromise("getObject", params)
|
||||
}
|
||||
|
||||
validatePrivateBucketConfiguration_(usePrivateBucket) {
|
||||
if (
|
||||
usePrivateBucket &&
|
||||
(!this.private_access_key_id_ || !this.private_bucket_)
|
||||
) {
|
||||
throw new MedusaError(
|
||||
MedusaError.Types.UNEXPECTED_STATE,
|
||||
"Private bucket is not configured"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
protected getClient(
|
||||
usePrivateBucket = false,
|
||||
additionalConfiguration: Partial<ClientConfiguration> = {}
|
||||
) {
|
||||
return new aws.S3({
|
||||
accessKeyId: usePrivateBucket
|
||||
? this.private_access_key_id_
|
||||
: this.accessKeyId_,
|
||||
secretAccessKey: usePrivateBucket
|
||||
? this.private_secret_access_key_
|
||||
: this.secretAccessKey_,
|
||||
endpoint: this.endpoint_,
|
||||
s3ForcePathStyle: this.s3ForcePathStyle_,
|
||||
signatureVersion: this.signatureVersion_,
|
||||
...additionalConfiguration,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default MinioService
|
||||
30
packages/medusa-file-minio/tsconfig.json
Normal file
30
packages/medusa-file-minio/tsconfig.json
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": ["es5", "es6", "es2019"],
|
||||
"target": "es5",
|
||||
"outDir": "./dist",
|
||||
"rootDir": "src",
|
||||
"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"
|
||||
]
|
||||
}
|
||||
@@ -23,37 +23,38 @@ Store uploaded files to your Medusa backend on S3.
|
||||
|
||||
1\. Run the following command in the directory of the Medusa backend:
|
||||
|
||||
```bash
|
||||
npm install medusa-file-s3
|
||||
```
|
||||
```bash
|
||||
npm install medusa-file-s3
|
||||
```
|
||||
|
||||
2\. Set the following environment variables in `.env`:
|
||||
|
||||
```bash
|
||||
S3_URL=<YOUR_BUCKET_URL>
|
||||
S3_BUCKET=<YOUR_BUCKET_NAME>
|
||||
S3_REGION=<YOUR_BUCKET_REGION>
|
||||
S3_ACCESS_KEY_ID=<YOUR_ACCESS_KEY_ID>
|
||||
S3_SECRET_ACCESS_KEY=<YOUR_SECRET_ACCESS_KEY>
|
||||
```
|
||||
```bash
|
||||
S3_URL=<YOUR_BUCKET_URL>
|
||||
S3_BUCKET=<YOUR_BUCKET_NAME>
|
||||
S3_REGION=<YOUR_BUCKET_REGION>
|
||||
S3_ACCESS_KEY_ID=<YOUR_ACCESS_KEY_ID>
|
||||
S3_SECRET_ACCESS_KEY=<YOUR_SECRET_ACCESS_KEY>
|
||||
```
|
||||
|
||||
3\. In `medusa-config.js` add the following at the end of the `plugins` array:
|
||||
|
||||
```js
|
||||
const plugins = [
|
||||
// ...
|
||||
{
|
||||
resolve: `medusa-file-s3`,
|
||||
options: {
|
||||
s3_url: process.env.S3_URL,
|
||||
bucket: process.env.S3_BUCKET,
|
||||
region: process.env.S3_REGION,
|
||||
access_key_id: process.env.S3_ACCESS_KEY_ID,
|
||||
secret_access_key: process.env.S3_SECRET_ACCESS_KEY,
|
||||
},
|
||||
```js
|
||||
const plugins = [
|
||||
// ...
|
||||
{
|
||||
resolve: `medusa-file-s3`,
|
||||
options: {
|
||||
s3_url: process.env.S3_URL,
|
||||
bucket: process.env.S3_BUCKET,
|
||||
region: process.env.S3_REGION,
|
||||
access_key_id: process.env.S3_ACCESS_KEY_ID,
|
||||
secret_access_key: process.env.S3_SECRET_ACCESS_KEY,
|
||||
aws_config_option: {},
|
||||
},
|
||||
]
|
||||
```
|
||||
},
|
||||
]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -61,9 +62,9 @@ Store uploaded files to your Medusa backend on S3.
|
||||
|
||||
1\. Run the following command in the directory of the Medusa backend to run the backend:
|
||||
|
||||
```bash
|
||||
npm run start
|
||||
```
|
||||
```bash
|
||||
npm run start
|
||||
```
|
||||
|
||||
2\. Upload an image for a product using the admin dashboard or using [the Admin APIs](https://docs.medusajs.com/api/admin#tag/Upload).
|
||||
|
||||
@@ -71,4 +72,4 @@ Store uploaded files to your Medusa backend on S3.
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- [S3 Plugin Documentation](https://docs.medusajs.com/plugins/file-service/s3)
|
||||
- [S3 Plugin Documentation](https://docs.medusajs.com/plugins/file-service/s3)
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
"name": "medusa-file-s3",
|
||||
"version": "1.1.12",
|
||||
"description": "AWS s3 file connector for Medusa",
|
||||
"main": "index.js",
|
||||
"main": "dist/index.js",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/medusajs/medusa",
|
||||
@@ -11,32 +14,23 @@
|
||||
"author": "Sebastian Mateos Nicolajsen",
|
||||
"license": "MIT",
|
||||
"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",
|
||||
"@medusajs/medusa": "1.8.0-rc.6",
|
||||
"cross-env": "^5.2.1",
|
||||
"jest": "^25.5.4",
|
||||
"medusa-interfaces": "^1.3.7",
|
||||
"medusa-test-utils": "^1.1.40"
|
||||
"medusa-test-utils": "^1.1.40",
|
||||
"typescript": "^4.9.5"
|
||||
},
|
||||
"scripts": {
|
||||
"prepare": "cross-env NODE_ENV=production yarn run build",
|
||||
"test": "jest --passWithNoTests src",
|
||||
"build": "babel src --out-dir . --ignore '**/__tests__','**/__mocks__'",
|
||||
"watch": "babel -w src --out-dir . --ignore '**/__tests__','**/__mocks__'"
|
||||
"build": "tsc",
|
||||
"watch": "tsc --watch"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"medusa-interfaces": "1.3.7"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/plugin-transform-classes": "^7.15.4",
|
||||
"aws-sdk": "^2.983.0",
|
||||
"body-parser": "^1.19.0",
|
||||
"express": "^4.17.1",
|
||||
|
||||
@@ -1,139 +0,0 @@
|
||||
import fs from "fs"
|
||||
import aws from "aws-sdk"
|
||||
import { parse } from "path"
|
||||
import { AbstractFileService } from "@medusajs/medusa"
|
||||
import stream from "stream"
|
||||
|
||||
class S3Service extends AbstractFileService {
|
||||
// eslint-disable-next-line no-empty-pattern
|
||||
constructor({}, options) {
|
||||
super({}, options)
|
||||
|
||||
this.bucket_ = options.bucket
|
||||
this.s3Url_ = options.s3_url
|
||||
this.accessKeyId_ = options.access_key_id
|
||||
this.secretAccessKey_ = options.secret_access_key
|
||||
this.region_ = options.region
|
||||
this.endpoint_ = options.endpoint
|
||||
this.awsConfigObject_ = options.aws_config_object
|
||||
|
||||
this.client_ = new aws.S3()
|
||||
}
|
||||
|
||||
upload(file) {
|
||||
this.updateAwsConfig()
|
||||
|
||||
return this.uploadFile(file)
|
||||
}
|
||||
|
||||
uploadProtected(file) {
|
||||
this.updateAwsConfig()
|
||||
|
||||
return this.uploadFile(file, { acl: "private" })
|
||||
}
|
||||
|
||||
uploadFile(file, options = { isProtected: false, acl: undefined }) {
|
||||
const parsedFilename = parse(file.originalname)
|
||||
const fileKey = `${parsedFilename.name}-${Date.now()}${parsedFilename.ext}`
|
||||
|
||||
const params = {
|
||||
ACL: options.acl ?? (options.isProtected ? "private" : "public-read"),
|
||||
Bucket: this.bucket_,
|
||||
Body: fs.createReadStream(file.path),
|
||||
Key: fileKey,
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
this.client_.upload(params, (err, data) => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
return
|
||||
}
|
||||
|
||||
resolve({ url: data.Location, key: data.Key })
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
async delete(file) {
|
||||
this.updateAwsConfig()
|
||||
|
||||
const params = {
|
||||
Bucket: this.bucket_,
|
||||
Key: `${file}`,
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
this.client_.deleteObject(params, (err, data) => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
return
|
||||
}
|
||||
resolve(data)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
async getUploadStreamDescriptor(fileData) {
|
||||
this.updateAwsConfig()
|
||||
|
||||
const pass = new stream.PassThrough()
|
||||
|
||||
const fileKey = `${fileData.name}.${fileData.ext}`
|
||||
const params = {
|
||||
ACL: fileData.acl ?? "private",
|
||||
Bucket: this.bucket_,
|
||||
Body: pass,
|
||||
Key: fileKey,
|
||||
}
|
||||
|
||||
return {
|
||||
writeStream: pass,
|
||||
promise: this.client_.upload(params).promise(),
|
||||
url: `${this.s3Url_}/${fileKey}`,
|
||||
fileKey,
|
||||
}
|
||||
}
|
||||
|
||||
async getDownloadStream(fileData) {
|
||||
this.updateAwsConfig()
|
||||
|
||||
const params = {
|
||||
Bucket: this.bucket_,
|
||||
Key: `${fileData.fileKey}`,
|
||||
}
|
||||
|
||||
return this.client_.getObject(params).createReadStream()
|
||||
}
|
||||
|
||||
async getPresignedDownloadUrl(fileData) {
|
||||
this.updateAwsConfig({
|
||||
signatureVersion: "v4",
|
||||
})
|
||||
|
||||
const params = {
|
||||
Bucket: this.bucket_,
|
||||
Key: `${fileData.fileKey}`,
|
||||
Expires: this.downloadUrlDuration,
|
||||
}
|
||||
|
||||
return await this.client_.getSignedUrlPromise("getObject", params)
|
||||
}
|
||||
|
||||
updateAwsConfig(additionalConfiguration = {}) {
|
||||
aws.config.setPromisesDependency(null)
|
||||
|
||||
const config = {
|
||||
...additionalConfiguration,
|
||||
accessKeyId: this.accessKeyId_,
|
||||
secretAccessKey: this.secretAccessKey_,
|
||||
region: this.region_,
|
||||
endpoint: this.endpoint_,
|
||||
...this.awsConfigObject_,
|
||||
}
|
||||
|
||||
aws.config.update(config, true)
|
||||
}
|
||||
}
|
||||
|
||||
export default S3Service
|
||||
157
packages/medusa-file-s3/src/services/s3.ts
Normal file
157
packages/medusa-file-s3/src/services/s3.ts
Normal file
@@ -0,0 +1,157 @@
|
||||
import fs from "fs"
|
||||
import aws from "aws-sdk"
|
||||
import { parse } from "path"
|
||||
import {
|
||||
AbstractFileService,
|
||||
DeleteFileType,
|
||||
FileServiceUploadResult,
|
||||
GetUploadedFileType,
|
||||
IFileService,
|
||||
UploadStreamDescriptorType,
|
||||
} from "@medusajs/medusa"
|
||||
import stream from "stream"
|
||||
import { PutObjectRequest } from "aws-sdk/clients/s3"
|
||||
import { ClientConfiguration } from "aws-sdk/clients/s3"
|
||||
|
||||
class S3Service extends AbstractFileService implements IFileService {
|
||||
protected bucket_: string
|
||||
protected s3Url_: string
|
||||
protected accessKeyId_: string
|
||||
protected secretAccessKey_: string
|
||||
protected region_: string
|
||||
protected endpoint_: string
|
||||
protected awsConfigObject_: any
|
||||
protected downloadFileDuration_: string
|
||||
|
||||
constructor({}, options) {
|
||||
super({}, options)
|
||||
|
||||
this.bucket_ = options.bucket
|
||||
this.s3Url_ = options.s3_url
|
||||
this.accessKeyId_ = options.access_key_id
|
||||
this.secretAccessKey_ = options.secret_access_key
|
||||
this.region_ = options.region
|
||||
this.endpoint_ = options.endpoint
|
||||
this.downloadFileDuration_ = options.download_file_duration
|
||||
this.awsConfigObject_ = options.aws_config_object ?? {}
|
||||
}
|
||||
|
||||
protected getClient(overwriteConfig: Partial<ClientConfiguration> = {}) {
|
||||
const config: ClientConfiguration = {
|
||||
accessKeyId: this.accessKeyId_,
|
||||
secretAccessKey: this.secretAccessKey_,
|
||||
region: this.region_,
|
||||
endpoint: this.endpoint_,
|
||||
...this.awsConfigObject_,
|
||||
...overwriteConfig,
|
||||
}
|
||||
|
||||
return new aws.S3(config)
|
||||
}
|
||||
|
||||
async upload(file: Express.Multer.File): Promise<FileServiceUploadResult> {
|
||||
return await this.uploadFile(file)
|
||||
}
|
||||
|
||||
async uploadProtected(file: Express.Multer.File) {
|
||||
return await this.uploadFile(file, { acl: "private" })
|
||||
}
|
||||
|
||||
async uploadFile(
|
||||
file: Express.Multer.File,
|
||||
options: { isProtected?: boolean; acl?: string } = {
|
||||
isProtected: false,
|
||||
acl: undefined,
|
||||
}
|
||||
) {
|
||||
const client = this.getClient()
|
||||
|
||||
const parsedFilename = parse(file.originalname)
|
||||
|
||||
const fileKey = `${parsedFilename.name}-${Date.now()}${parsedFilename.ext}`
|
||||
|
||||
const params = {
|
||||
ACL: options.acl ?? (options.isProtected ? "private" : "public-read"),
|
||||
Bucket: this.bucket_,
|
||||
Body: fs.createReadStream(file.path),
|
||||
Key: fileKey,
|
||||
ContentType: file.mimetype,
|
||||
}
|
||||
|
||||
const result = await client.upload(params).promise()
|
||||
|
||||
return {
|
||||
url: result.Location,
|
||||
key: result.Key,
|
||||
}
|
||||
}
|
||||
|
||||
async delete(file: DeleteFileType): Promise<void> {
|
||||
const client = this.getClient()
|
||||
|
||||
const params = {
|
||||
Bucket: this.bucket_,
|
||||
Key: `${file}`,
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
client.deleteObject(params, (err, data) => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
return
|
||||
}
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
async getUploadStreamDescriptor(fileData: UploadStreamDescriptorType) {
|
||||
const client = this.getClient()
|
||||
const pass = new stream.PassThrough()
|
||||
|
||||
const fileKey = `${fileData.name}.${fileData.ext}`
|
||||
const params: PutObjectRequest = {
|
||||
ACL: fileData.acl ?? "private",
|
||||
Bucket: this.bucket_,
|
||||
Body: pass,
|
||||
Key: fileKey,
|
||||
ContentType: fileData.contentType as string,
|
||||
}
|
||||
|
||||
return {
|
||||
writeStream: pass,
|
||||
promise: client.upload(params).promise(),
|
||||
url: `${this.s3Url_}/${fileKey}`,
|
||||
fileKey,
|
||||
}
|
||||
}
|
||||
|
||||
async getDownloadStream(
|
||||
fileData: GetUploadedFileType
|
||||
): Promise<NodeJS.ReadableStream> {
|
||||
const client = this.getClient()
|
||||
|
||||
const params = {
|
||||
Bucket: this.bucket_,
|
||||
Key: `${fileData.fileKey}`,
|
||||
}
|
||||
|
||||
return await client.getObject(params).createReadStream()
|
||||
}
|
||||
|
||||
async getPresignedDownloadUrl(
|
||||
fileData: GetUploadedFileType
|
||||
): Promise<string> {
|
||||
const client = this.getClient({ signatureVersion: "v4" })
|
||||
|
||||
const params = {
|
||||
Bucket: this.bucket_,
|
||||
Key: `${fileData.fileKey}`,
|
||||
Expires: this.downloadFileDuration_,
|
||||
}
|
||||
|
||||
return await client.getSignedUrlPromise("getObject", params)
|
||||
}
|
||||
}
|
||||
|
||||
export default S3Service
|
||||
30
packages/medusa-file-s3/tsconfig.json
Normal file
30
packages/medusa-file-s3/tsconfig.json
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": ["es5", "es6", "es2019"],
|
||||
"target": "es5",
|
||||
"outDir": "./dist",
|
||||
"rootDir": "src",
|
||||
"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
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": [
|
||||
"dist",
|
||||
"src/**/__tests__",
|
||||
"src/**/__mocks__",
|
||||
"src/**/__fixtures__",
|
||||
"node_modules"
|
||||
]
|
||||
}
|
||||
217
yarn.lock
217
yarn.lock
@@ -262,7 +262,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@babel/cli@npm:^7.12.1, @babel/cli@npm:^7.14.3, @babel/cli@npm:^7.15.4, @babel/cli@npm:^7.16.0, @babel/cli@npm:^7.7.5":
|
||||
"@babel/cli@npm:^7.12.1, @babel/cli@npm:^7.14.3, @babel/cli@npm:^7.15.4, @babel/cli@npm:^7.7.5":
|
||||
version: 7.18.6
|
||||
resolution: "@babel/cli@npm:7.18.6"
|
||||
dependencies:
|
||||
@@ -995,7 +995,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@babel/node@npm:^7.12.6, @babel/node@npm:^7.15.4, @babel/node@npm:^7.16.0, @babel/node@npm:^7.7.4":
|
||||
"@babel/node@npm:^7.12.6, @babel/node@npm:^7.15.4, @babel/node@npm:^7.7.4":
|
||||
version: 7.18.6
|
||||
resolution: "@babel/node@npm:7.18.6"
|
||||
dependencies:
|
||||
@@ -1113,7 +1113,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@babel/plugin-proposal-class-properties@npm:^7.0.0, @babel/plugin-proposal-class-properties@npm:^7.10.4, @babel/plugin-proposal-class-properties@npm:^7.12.1, @babel/plugin-proposal-class-properties@npm:^7.14.0, @babel/plugin-proposal-class-properties@npm:^7.14.5, @babel/plugin-proposal-class-properties@npm:^7.16.0, @babel/plugin-proposal-class-properties@npm:^7.18.6, @babel/plugin-proposal-class-properties@npm:^7.7.4":
|
||||
"@babel/plugin-proposal-class-properties@npm:^7.0.0, @babel/plugin-proposal-class-properties@npm:^7.10.4, @babel/plugin-proposal-class-properties@npm:^7.12.1, @babel/plugin-proposal-class-properties@npm:^7.14.0, @babel/plugin-proposal-class-properties@npm:^7.14.5, @babel/plugin-proposal-class-properties@npm:^7.18.6, @babel/plugin-proposal-class-properties@npm:^7.7.4":
|
||||
version: 7.18.6
|
||||
resolution: "@babel/plugin-proposal-class-properties@npm:7.18.6"
|
||||
dependencies:
|
||||
@@ -1714,7 +1714,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@babel/plugin-transform-classes@npm:^7.0.0, @babel/plugin-transform-classes@npm:^7.10.4, @babel/plugin-transform-classes@npm:^7.12.1, @babel/plugin-transform-classes@npm:^7.15.4, @babel/plugin-transform-classes@npm:^7.16.0, @babel/plugin-transform-classes@npm:^7.18.6, @babel/plugin-transform-classes@npm:^7.9.5":
|
||||
"@babel/plugin-transform-classes@npm:^7.0.0, @babel/plugin-transform-classes@npm:^7.10.4, @babel/plugin-transform-classes@npm:^7.12.1, @babel/plugin-transform-classes@npm:^7.15.4, @babel/plugin-transform-classes@npm:^7.18.6, @babel/plugin-transform-classes@npm:^7.9.5":
|
||||
version: 7.18.8
|
||||
resolution: "@babel/plugin-transform-classes@npm:7.18.8"
|
||||
dependencies:
|
||||
@@ -1872,7 +1872,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@babel/plugin-transform-instanceof@npm:^7.10.4, @babel/plugin-transform-instanceof@npm:^7.12.1, @babel/plugin-transform-instanceof@npm:^7.12.13, @babel/plugin-transform-instanceof@npm:^7.14.5, @babel/plugin-transform-instanceof@npm:^7.16.0, @babel/plugin-transform-instanceof@npm:^7.8.3":
|
||||
"@babel/plugin-transform-instanceof@npm:^7.10.4, @babel/plugin-transform-instanceof@npm:^7.12.1, @babel/plugin-transform-instanceof@npm:^7.12.13, @babel/plugin-transform-instanceof@npm:^7.14.5, @babel/plugin-transform-instanceof@npm:^7.8.3":
|
||||
version: 7.18.6
|
||||
resolution: "@babel/plugin-transform-instanceof@npm:7.18.6"
|
||||
dependencies:
|
||||
@@ -2195,7 +2195,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@babel/plugin-transform-runtime@npm:^7.11.5, @babel/plugin-transform-runtime@npm:^7.12.1, @babel/plugin-transform-runtime@npm:^7.15.0, @babel/plugin-transform-runtime@npm:^7.16.4, @babel/plugin-transform-runtime@npm:^7.7.6":
|
||||
"@babel/plugin-transform-runtime@npm:^7.11.5, @babel/plugin-transform-runtime@npm:^7.12.1, @babel/plugin-transform-runtime@npm:^7.15.0, @babel/plugin-transform-runtime@npm:^7.7.6":
|
||||
version: 7.18.6
|
||||
resolution: "@babel/plugin-transform-runtime@npm:7.18.6"
|
||||
dependencies:
|
||||
@@ -2426,7 +2426,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@babel/preset-env@npm:^7.11.5, @babel/preset-env@npm:^7.12.11, @babel/preset-env@npm:^7.12.7, @babel/preset-env@npm:^7.15.4, @babel/preset-env@npm:^7.15.6, @babel/preset-env@npm:^7.16.4, @babel/preset-env@npm:^7.7.5":
|
||||
"@babel/preset-env@npm:^7.11.5, @babel/preset-env@npm:^7.12.11, @babel/preset-env@npm:^7.12.7, @babel/preset-env@npm:^7.15.4, @babel/preset-env@npm:^7.15.6, @babel/preset-env@npm:^7.7.5":
|
||||
version: 7.18.6
|
||||
resolution: "@babel/preset-env@npm:7.18.6"
|
||||
dependencies:
|
||||
@@ -2568,7 +2568,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@babel/register@npm:^7.11.5, @babel/register@npm:^7.12.1, @babel/register@npm:^7.15.3, @babel/register@npm:^7.16.0, @babel/register@npm:^7.18.6, @babel/register@npm:^7.7.4":
|
||||
"@babel/register@npm:^7.11.5, @babel/register@npm:^7.12.1, @babel/register@npm:^7.15.3, @babel/register@npm:^7.18.6, @babel/register@npm:^7.7.4":
|
||||
version: 7.18.6
|
||||
resolution: "@babel/register@npm:7.18.6"
|
||||
dependencies:
|
||||
@@ -2615,7 +2615,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.10.0, @babel/runtime@npm:^7.10.2, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.15.4, @babel/runtime@npm:^7.16.3, @babel/runtime@npm:^7.17.8, @babel/runtime@npm:^7.18.0, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.5.0, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.7.2, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.9.2, @babel/runtime@npm:^7.9.6":
|
||||
"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.10.0, @babel/runtime@npm:^7.10.2, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.15.4, @babel/runtime@npm:^7.17.8, @babel/runtime@npm:^7.18.0, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.5.0, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.7.2, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.9.2, @babel/runtime@npm:^7.9.6":
|
||||
version: 7.18.6
|
||||
resolution: "@babel/runtime@npm:7.18.6"
|
||||
dependencies:
|
||||
@@ -6059,6 +6059,44 @@ __metadata:
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@medusajs/medusa-cli@npm:1.3.9-rc.2":
|
||||
version: 1.3.9-rc.2
|
||||
resolution: "@medusajs/medusa-cli@npm:1.3.9-rc.2"
|
||||
dependencies:
|
||||
"@medusajs/utils": 0.0.2-rc.2
|
||||
axios: ^0.21.4
|
||||
chalk: ^4.0.0
|
||||
configstore: 5.0.1
|
||||
core-js: ^3.6.5
|
||||
dotenv: ^8.2.0
|
||||
execa: ^5.1.1
|
||||
fs-exists-cached: ^1.0.0
|
||||
fs-extra: ^10.0.0
|
||||
hosted-git-info: ^4.0.2
|
||||
inquirer: ^8.0.0
|
||||
is-valid-path: ^0.1.1
|
||||
meant: ^1.0.3
|
||||
medusa-core-utils: ^1.2.0-rc.0
|
||||
medusa-telemetry: 0.0.16
|
||||
open: ^8.0.6
|
||||
ora: ^5.4.1
|
||||
pg-god: ^1.0.12
|
||||
prompts: ^2.4.2
|
||||
regenerator-runtime: ^0.13.11
|
||||
resolve-cwd: ^3.0.0
|
||||
semver: ^7.3.8
|
||||
sqlite3: ^5.0.2
|
||||
stack-trace: ^0.0.10
|
||||
ulid: ^2.3.0
|
||||
url: ^0.11.0
|
||||
winston: ^3.8.2
|
||||
yargs: ^15.3.1
|
||||
bin:
|
||||
medusa: cli.js
|
||||
checksum: 480011b6850187191c13dd503b894190b102dda0ae90d0413bfcbfa33083310b776a5f504434c70f1dd44721f669d8b9746561296e6a133d9c51526d9a9af88f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@medusajs/medusa-js@2.0.2, @medusajs/medusa-js@workspace:packages/medusa-js":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@medusajs/medusa-js@workspace:packages/medusa-js"
|
||||
@@ -6175,6 +6213,67 @@ __metadata:
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@medusajs/medusa@npm:1.8.0-rc.6":
|
||||
version: 1.8.0-rc.6
|
||||
resolution: "@medusajs/medusa@npm:1.8.0-rc.6"
|
||||
dependencies:
|
||||
"@medusajs/medusa-cli": 1.3.9-rc.2
|
||||
"@medusajs/modules-sdk": 0.1.0-rc.4
|
||||
"@medusajs/utils": 0.0.2-rc.2
|
||||
"@types/ioredis": ^4.28.10
|
||||
"@types/lodash": ^4.14.191
|
||||
awilix: ^8.0.0
|
||||
body-parser: ^1.19.0
|
||||
boxen: ^5.0.1
|
||||
bullmq: ^3.5.6
|
||||
chokidar: ^3.4.2
|
||||
class-transformer: ^0.5.1
|
||||
class-validator: ^0.13.2
|
||||
connect-redis: ^5.0.0
|
||||
cookie-parser: ^1.4.6
|
||||
core-js: ^3.6.5
|
||||
cors: ^2.8.5
|
||||
cross-spawn: ^7.0.3
|
||||
dotenv: ^16.0.3
|
||||
express: ^4.17.1
|
||||
express-session: ^1.17.3
|
||||
fs-exists-cached: ^1.0.0
|
||||
glob: ^7.1.6
|
||||
ioredis: ^5.2.5
|
||||
ioredis-mock: ^5.6.0
|
||||
iso8601-duration: ^1.3.0
|
||||
jsonwebtoken: ^8.5.1
|
||||
lodash: ^4.17.21
|
||||
medusa-core-utils: ^1.2.0-rc.0
|
||||
medusa-telemetry: ^0.0.16
|
||||
medusa-test-utils: ^1.1.40-rc.0
|
||||
morgan: ^1.9.1
|
||||
multer: ^1.4.4
|
||||
node-schedule: ^2.1.1
|
||||
papaparse: ^5.3.2
|
||||
passport: ^0.4.1
|
||||
passport-http-bearer: ^1.0.1
|
||||
passport-jwt: ^4.0.1
|
||||
passport-local: ^1.0.0
|
||||
randomatic: ^3.1.1
|
||||
redis: ^3.0.2
|
||||
reflect-metadata: ^0.1.13
|
||||
regenerator-runtime: ^0.13.11
|
||||
request-ip: ^2.1.3
|
||||
scrypt-kdf: ^2.0.1
|
||||
ulid: ^2.3.0
|
||||
uuid: ^8.3.2
|
||||
winston: ^3.8.2
|
||||
peerDependencies:
|
||||
"@medusajs/types": 0.0.2-rc.1
|
||||
medusa-interfaces: 1.3.7-rc.0
|
||||
typeorm: ^0.3.11
|
||||
bin:
|
||||
medusa: cli.js
|
||||
checksum: 8260fc5647459569e0c45a2ce86c0a3290085182ec2fb89f8e7a00dafa85c2f6932442a4566911af8962d9a75053b078468b9fa591b9828f2f97a58c3c32fd57
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@medusajs/modules-sdk@1.8.2, @medusajs/modules-sdk@workspace:packages/modules-sdk":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@medusajs/modules-sdk@workspace:packages/modules-sdk"
|
||||
@@ -6192,6 +6291,20 @@ __metadata:
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@medusajs/modules-sdk@npm:0.1.0-rc.4":
|
||||
version: 0.1.0-rc.4
|
||||
resolution: "@medusajs/modules-sdk@npm:0.1.0-rc.4"
|
||||
dependencies:
|
||||
"@medusajs/types": 0.0.2-rc.1
|
||||
"@medusajs/utils": 0.0.2-rc.2
|
||||
awilix: ^8.0.0
|
||||
glob: 7.1.6
|
||||
medusa-telemetry: ^0.0.16
|
||||
resolve-cwd: ^3.0.0
|
||||
checksum: f5d9d6ff6db08dfa4a7e2072b414ab608f89420cecfbcb992ce4e710b309efbbeb3b2d9c0f74c924658b86399f89fafd740a860e592d581c27e0a68bf7920724
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@medusajs/oas-github-ci@workspace:packages/oas/oas-github-ci":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@medusajs/oas-github-ci@workspace:packages/oas/oas-github-ci"
|
||||
@@ -6266,6 +6379,13 @@ __metadata:
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@medusajs/types@npm:0.0.2-rc.1":
|
||||
version: 0.0.2-rc.1
|
||||
resolution: "@medusajs/types@npm:0.0.2-rc.1"
|
||||
checksum: 05c122211741d540aad426cc164accd92701b66bde68be5c50d85627959c87295c49507fe5b09136689898fec810b6a7833076675f67039a3b77de6ef4c6ee9e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@medusajs/utils@1.8.1, @medusajs/utils@workspace:packages/utils":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "@medusajs/utils@workspace:packages/utils"
|
||||
@@ -6284,6 +6404,19 @@ __metadata:
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"@medusajs/utils@npm:0.0.2-rc.2":
|
||||
version: 0.0.2-rc.2
|
||||
resolution: "@medusajs/utils@npm:0.0.2-rc.2"
|
||||
dependencies:
|
||||
awilix: ^8.0.0
|
||||
class-transformer: ^0.5.1
|
||||
class-validator: ^0.13.2
|
||||
typeorm: ^0.3.11
|
||||
ulid: ^2.3.0
|
||||
checksum: 5404298118fcd8009622f55b44fecaf2deaf0ec948977271e05384541dc6922c0ab2406e7b94aa498b475ba73793fb8e3ebc57ac66a01382557f1f4c3bdda8cd
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@microsoft/fetch-event-source@npm:2.0.1":
|
||||
version: 2.0.1
|
||||
resolution: "@microsoft/fetch-event-source@npm:2.0.1"
|
||||
@@ -13984,7 +14117,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"aws-sdk@npm:^2.1043.0, aws-sdk@npm:^2.710.0, aws-sdk@npm:^2.983.0":
|
||||
"aws-sdk@npm:^2.710.0, aws-sdk@npm:^2.983.0":
|
||||
version: 2.1172.0
|
||||
resolution: "aws-sdk@npm:2.1172.0"
|
||||
dependencies:
|
||||
@@ -20742,7 +20875,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"fengari-interop@npm:^0.1.3":
|
||||
"fengari-interop@npm:^0.1.2, fengari-interop@npm:^0.1.3":
|
||||
version: 0.1.3
|
||||
resolution: "fengari-interop@npm:0.1.3"
|
||||
peerDependencies:
|
||||
@@ -23811,6 +23944,21 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ioredis-mock@npm:^5.6.0":
|
||||
version: 5.9.1
|
||||
resolution: "ioredis-mock@npm:5.9.1"
|
||||
dependencies:
|
||||
fengari: ^0.1.4
|
||||
fengari-interop: ^0.1.2
|
||||
lodash: ^4.17.21
|
||||
standard-as-callback: ^2.1.0
|
||||
peerDependencies:
|
||||
ioredis: 4.x
|
||||
redis-commands: 1.x
|
||||
checksum: 0b898273788c38ec617a3cf94df93c41a8f05a1cf57dfbbc3a97ea72fc07882be3872d55c915e49e615892ec20129351be7bb68e1beb7563a01eec157cc84088
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ioredis@npm:^4.27.9":
|
||||
version: 4.28.5
|
||||
resolution: "ioredis@npm:4.28.5"
|
||||
@@ -29071,7 +29219,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"medusa-core-utils@1.2.0, medusa-core-utils@^1.2.0, medusa-core-utils@workspace:packages/medusa-core-utils":
|
||||
"medusa-core-utils@1.2.0, medusa-core-utils@^1.2.0, medusa-core-utils@^1.2.0-rc.0, medusa-core-utils@workspace:packages/medusa-core-utils":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "medusa-core-utils@workspace:packages/medusa-core-utils"
|
||||
dependencies:
|
||||
@@ -29114,25 +29262,15 @@ __metadata:
|
||||
version: 0.0.0-use.local
|
||||
resolution: "medusa-file-minio@workspace:packages/medusa-file-minio"
|
||||
dependencies:
|
||||
"@babel/cli": ^7.16.0
|
||||
"@babel/core": ^7.16.0
|
||||
"@babel/node": ^7.16.0
|
||||
"@babel/plugin-proposal-class-properties": ^7.16.0
|
||||
"@babel/plugin-transform-classes": ^7.16.0
|
||||
"@babel/plugin-transform-instanceof": ^7.16.0
|
||||
"@babel/plugin-transform-runtime": ^7.16.4
|
||||
"@babel/preset-env": ^7.16.4
|
||||
"@babel/register": ^7.16.0
|
||||
"@babel/runtime": ^7.16.3
|
||||
aws-sdk: ^2.1043.0
|
||||
"@medusajs/medusa": 1.8.0-rc.6
|
||||
aws-sdk: ^2.983.0
|
||||
body-parser: ^1.19.0
|
||||
client-sessions: ^0.8.0
|
||||
cross-env: ^5.2.1
|
||||
express: ^4.17.1
|
||||
jest: ^25.5.4
|
||||
medusa-core-utils: ^1.2.0
|
||||
medusa-interfaces: ^1.3.7
|
||||
medusa-test-utils: ^1.1.40
|
||||
typescript: ^4.9.5
|
||||
peerDependencies:
|
||||
medusa-interfaces: 1.3.7
|
||||
languageName: unknown
|
||||
@@ -29142,25 +29280,16 @@ __metadata:
|
||||
version: 0.0.0-use.local
|
||||
resolution: "medusa-file-s3@workspace:packages/medusa-file-s3"
|
||||
dependencies:
|
||||
"@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-classes": ^7.15.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
|
||||
"@medusajs/medusa": 1.8.0-rc.6
|
||||
aws-sdk: ^2.983.0
|
||||
body-parser: ^1.19.0
|
||||
client-sessions: ^0.8.0
|
||||
cross-env: ^5.2.1
|
||||
express: ^4.17.1
|
||||
jest: ^25.5.4
|
||||
medusa-core-utils: ^1.2.0
|
||||
medusa-interfaces: ^1.3.7
|
||||
medusa-test-utils: ^1.1.40
|
||||
typescript: ^4.9.5
|
||||
peerDependencies:
|
||||
medusa-interfaces: 1.3.7
|
||||
languageName: unknown
|
||||
@@ -29840,7 +29969,7 @@ __metadata:
|
||||
languageName: unknown
|
||||
linkType: soft
|
||||
|
||||
"medusa-test-utils@^1.1.40, medusa-test-utils@workspace:packages/medusa-test-utils":
|
||||
"medusa-test-utils@^1.1.40, medusa-test-utils@^1.1.40-rc.0, medusa-test-utils@workspace:packages/medusa-test-utils":
|
||||
version: 0.0.0-use.local
|
||||
resolution: "medusa-test-utils@workspace:packages/medusa-test-utils"
|
||||
dependencies:
|
||||
@@ -30757,7 +30886,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"multer@npm:^1.4.3":
|
||||
"multer@npm:^1.4.3, multer@npm:^1.4.4":
|
||||
version: 1.4.4
|
||||
resolution: "multer@npm:1.4.4"
|
||||
dependencies:
|
||||
@@ -32495,6 +32624,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"passport@npm:^0.4.1":
|
||||
version: 0.4.1
|
||||
resolution: "passport@npm:0.4.1"
|
||||
dependencies:
|
||||
passport-strategy: 1.x.x
|
||||
pause: 0.0.1
|
||||
checksum: aa1a8eb2e991368734ae1e33d354c94a02c5fcd27c4ef25c3c303b4f3df1e05512ac0159e608cedbfc8c544c166735a153124cfa3bd8d48fb01f5ded500f0c5f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"passport@npm:^0.6.0":
|
||||
version: 0.6.0
|
||||
resolution: "passport@npm:0.6.0"
|
||||
@@ -39833,7 +39972,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"typeorm@npm:^0.3.14":
|
||||
"typeorm@npm:^0.3.11, typeorm@npm:^0.3.14":
|
||||
version: 0.3.14
|
||||
resolution: "typeorm@npm:0.3.14"
|
||||
dependencies:
|
||||
|
||||
Reference in New Issue
Block a user