@lodashventure/medusa-upload-gcs 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ const widgetModule = { widgets: [] };
3
+ const routeModule = {
4
+ routes: []
5
+ };
6
+ const menuItemModule = {
7
+ menuItems: []
8
+ };
9
+ const formModule = { customFields: {} };
10
+ const displayModule = {
11
+ displays: {}
12
+ };
13
+ const plugin = {
14
+ widgetModule,
15
+ routeModule,
16
+ menuItemModule,
17
+ formModule,
18
+ displayModule
19
+ };
20
+ module.exports = plugin;
@@ -0,0 +1,21 @@
1
+ const widgetModule = { widgets: [] };
2
+ const routeModule = {
3
+ routes: []
4
+ };
5
+ const menuItemModule = {
6
+ menuItems: []
7
+ };
8
+ const formModule = { customFields: {} };
9
+ const displayModule = {
10
+ displays: {}
11
+ };
12
+ const plugin = {
13
+ widgetModule,
14
+ routeModule,
15
+ menuItemModule,
16
+ formModule,
17
+ displayModule
18
+ };
19
+ export {
20
+ plugin as default
21
+ };
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const gcs_file_1 = require("./service/gcs-file");
4
+ const utils_1 = require("@medusajs/framework/utils");
5
+ exports.default = (0, utils_1.ModuleProvider)(utils_1.Modules.FILE, {
6
+ services: [gcs_file_1.GcsFileService],
7
+ });
8
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvcHJvdmlkZXJzL2ZpbGUtZ2NzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsaURBQW9EO0FBQ3BELHFEQUFvRTtBQUVwRSxrQkFBZSxJQUFBLHNCQUFjLEVBQUMsZUFBTyxDQUFDLElBQUksRUFBRTtJQUMxQyxRQUFRLEVBQUUsQ0FBQyx5QkFBYyxDQUFDO0NBQzNCLENBQUMsQ0FBQyJ9
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GcsFileService = void 0;
4
+ const storage_1 = require("@google-cloud/storage");
5
+ const utils_1 = require("@medusajs/framework/utils");
6
+ const uuid_1 = require("uuid");
7
+ class GcsFileService extends utils_1.AbstractFileProviderService {
8
+ constructor({ logger }, options) {
9
+ super();
10
+ this.basePublicUrl_ = "";
11
+ this.logger_ = logger;
12
+ //setup storage client
13
+ if (options.credentials) {
14
+ this.privateStorage_ = new storage_1.Storage({
15
+ credentials: {
16
+ client_email: options.credentials.client_email,
17
+ private_key: options.credentials.private_key,
18
+ },
19
+ });
20
+ }
21
+ else {
22
+ //Use Application Default credentials
23
+ this.privateStorage_ = new storage_1.Storage();
24
+ }
25
+ //Setup public bucket name
26
+ this.publicBucketName_ = options.publicBucketName;
27
+ //Setup private bucket name
28
+ this.privateBucketName_ = options.privateBucketName;
29
+ //base public url for get file in internet (e.g. cdn url)
30
+ this.basePublicUrl_ = options.basePublicUrl || "";
31
+ }
32
+ /**
33
+ * This method is used to transform the Google Cloud URL to a CDN URL. (Only for public bucket)
34
+ * @param googleCloudURL
35
+ * @returns
36
+ */
37
+ transformGoogleCloudURLtoCDN(googleCloudURL) {
38
+ // Define the base URLs
39
+ const googleCloudBaseURL = `https://storage.googleapis.com/${this.publicBucketName_}/`;
40
+ // Extract the file identifier from the Google Cloud URL
41
+ const fileIdentifier = googleCloudURL.replace(googleCloudBaseURL, "");
42
+ // Construct the CDN URL
43
+ const cdnURL = `${this.basePublicUrl_}${fileIdentifier}`;
44
+ return cdnURL;
45
+ }
46
+ /**
47
+ * This method is used to upload file(public bucket) to cloud storage.
48
+ * @param fileData
49
+ * @returns FileServiceUploadResult
50
+ */
51
+ async upload(fileData) {
52
+ try {
53
+ //key for use identifier when client get this
54
+ const key = (0, uuid_1.v4)();
55
+ // Extracting the file name without the extension
56
+ const destination = `${key}/${fileData.filename}`;
57
+ const file = await this.privateStorage_
58
+ .bucket(this.publicBucketName_)
59
+ .file(destination);
60
+ //get content of file
61
+ const contentBuffer = Buffer.from(fileData.content, "binary");
62
+ await file.save(contentBuffer, {
63
+ public: true,
64
+ });
65
+ const publicUrl = await file.publicUrl();
66
+ return {
67
+ url: publicUrl,
68
+ key: destination,
69
+ };
70
+ }
71
+ catch (error) {
72
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, error?.message || "Upload file to bucket error.");
73
+ }
74
+ }
75
+ async delete(fileData) {
76
+ try {
77
+ //search file in bucket
78
+ const isPrivate = fileData?.isPrivate === undefined ? true : fileData.isPrivate;
79
+ const file = this.privateStorage_
80
+ .bucket(isPrivate ? this.privateBucketName_ : this.publicBucketName_)
81
+ .file(fileData.fileKey);
82
+ const [isExist] = await file.exists();
83
+ if (isExist) {
84
+ //delete
85
+ await file.delete();
86
+ return;
87
+ }
88
+ else {
89
+ //not found file
90
+ this.logger_.warn("Not found file, file: " + fileData.fileKey);
91
+ }
92
+ }
93
+ catch (error) {
94
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, error?.message || "Delete file error.");
95
+ }
96
+ }
97
+ async getPresignedDownloadUrl(fileData) {
98
+ try {
99
+ const EXPIRATION_TIME = 15 * 60 * 1000; // 15 minutes
100
+ const file = this.privateStorage_
101
+ .bucket(this.privateBucketName_)
102
+ .file(fileData.fileKey);
103
+ const [isExist] = await file.exists();
104
+ if (!isExist) {
105
+ //Not found file
106
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.NOT_FOUND, "Not found file.");
107
+ }
108
+ //config for generate url
109
+ const options = {
110
+ version: "v4",
111
+ action: "read",
112
+ expires: Date.now() + EXPIRATION_TIME,
113
+ };
114
+ const [url] = await file.getSignedUrl(options);
115
+ return url;
116
+ }
117
+ catch (error) {
118
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, error?.message || "Download stream file error.");
119
+ }
120
+ }
121
+ }
122
+ exports.GcsFileService = GcsFileService;
123
+ GcsFileService.identifier = "gcs";
124
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2NzLWZpbGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvcHJvdmlkZXJzL2ZpbGUtZ2NzL3NlcnZpY2UvZ2NzLWZpbGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsbURBQTRFO0FBVzVFLHFEQUdtQztBQUluQywrQkFBb0M7QUFrQnBDLE1BQWEsY0FBZSxTQUFRLG1DQUEyQjtJQVM3RCxZQUFZLEVBQUUsTUFBTSxFQUFFLEVBQUUsT0FBTztRQUM3QixLQUFLLEVBQUUsQ0FBQztRQUxBLG1CQUFjLEdBQVcsRUFBRSxDQUFDO1FBTXBDLElBQUksQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDO1FBQ3RCLHNCQUFzQjtRQUN0QixJQUFJLE9BQU8sQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUN4QixJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksaUJBQU8sQ0FBQztnQkFDakMsV0FBVyxFQUFFO29CQUNYLFlBQVksRUFBRSxPQUFPLENBQUMsV0FBVyxDQUFDLFlBQVk7b0JBQzlDLFdBQVcsRUFBRSxPQUFPLENBQUMsV0FBVyxDQUFDLFdBQVc7aUJBQzdDO2FBQ0YsQ0FBQyxDQUFDO1FBQ0wsQ0FBQzthQUFNLENBQUM7WUFDTixxQ0FBcUM7WUFDckMsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLGlCQUFPLEVBQUUsQ0FBQztRQUN2QyxDQUFDO1FBQ0QsMEJBQTBCO1FBQzFCLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxPQUFPLENBQUMsZ0JBQWdCLENBQUM7UUFFbEQsMkJBQTJCO1FBQzNCLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxPQUFPLENBQUMsaUJBQWlCLENBQUM7UUFFcEQseURBQXlEO1FBQ3pELElBQUksQ0FBQyxjQUFjLEdBQUcsT0FBTyxDQUFDLGFBQWEsSUFBSSxFQUFFLENBQUM7SUFDcEQsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCw0QkFBNEIsQ0FBQyxjQUFzQjtRQUNqRCx1QkFBdUI7UUFDdkIs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
package/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # Medusa Plugin File-GCS
2
+
3
+ ## How to install
4
+ 1. yarn add medusa-upload-gcs
5
+
6
+ 2. configure your medusa backend `medusa-config.ts`
7
+ ```ts
8
+ module.exports = defineConfig({
9
+ // ... rest of the config
10
+ modules: [
11
+ // ... rest of the modules
12
+ {
13
+ resolve: "@medusajs/medusa/file",
14
+ options: {
15
+ providers: [
16
+ {
17
+ resolve: "medusa-upload-gcs/providers/file-gcs",
18
+ id: "gcs",
19
+ options: {
20
+ credentials: {
21
+ client_email: process.env.CLIENT_EMAIL,
22
+ private_key: process.env.PRIVATE_KEY,
23
+ },
24
+ privateBucketName: process.env.BUCKET_NAME,
25
+ publicBucketName: process.env.BUCKET_NAME,
26
+ basePublicUrl: process.env.GCP_STORAGE_BASE_PUBLIC_URL,
27
+ },
28
+ },
29
+ ],
30
+ },
31
+ },
32
+ ],
33
+ });
34
+ ```
35
+ 1. add variables to .env
36
+ ```
37
+ CLIENT_EMAIL=<client@email.com>
38
+ PRIVATE_KEY="<private-key>"
39
+ BUCKET_NAME=<bucket-name>
40
+ GCP_STORAGE_BASE_PUBLIC_URL=<base-public-url, mostly https://storage.googleapis.com>
41
+ ```
42
+
43
+ 1. all done now just start your medusa backend
44
+ `yarn dev` `yarn start` or whatever you use to start your backend
package/package.json ADDED
@@ -0,0 +1,79 @@
1
+ {
2
+ "name": "@lodashventure/medusa-upload-gcs",
3
+ "version": "0.0.1",
4
+ "description": "A starter for Medusa plugins.",
5
+ "author": "Medusa (https://medusajs.com)",
6
+ "license": "MIT",
7
+ "files": [
8
+ ".medusa/server"
9
+ ],
10
+ "exports": {
11
+ "./package.json": "./package.json",
12
+ "./workflows": "./.medusa/server/src/workflows/index.js",
13
+ "./.medusa/server/src/modules/*": "./.medusa/server/src/modules/*/index.js",
14
+ "./modules/*": "./.medusa/server/src/modules/*/index.js",
15
+ "./providers/*": "./.medusa/server/src/providers/*/index.js",
16
+ "./*": "./.medusa/server/src/*.js"
17
+ },
18
+ "keywords": [
19
+ "medusa",
20
+ "plugin",
21
+ "medusa-plugin-other",
22
+ "medusa-plugin",
23
+ "medusa-v2"
24
+ ],
25
+ "scripts": {
26
+ "build": "medusa plugin:build",
27
+ "dev": "medusa plugin:develop",
28
+ "prepublishOnly": "medusa plugin:build"
29
+ },
30
+ "devDependencies": {
31
+ "@medusajs/admin-sdk": "2.10.0",
32
+ "@medusajs/cli": "2.10.0",
33
+ "@medusajs/framework": "2.10.0",
34
+ "@medusajs/icons": "^2.10.0",
35
+ "@medusajs/medusa": "2.10.0",
36
+ "@medusajs/test-utils": "2.10.0",
37
+ "@medusajs/ui": "4.0.17",
38
+ "@mikro-orm/cli": "6.4.3",
39
+ "@mikro-orm/core": "6.4.3",
40
+ "@mikro-orm/knex": "6.4.3",
41
+ "@mikro-orm/migrations": "6.4.3",
42
+ "@mikro-orm/postgresql": "6.4.3",
43
+ "@swc/core": "1.5.7",
44
+ "@types/node": "^20.0.0",
45
+ "@types/react": "^18.3.2",
46
+ "@types/react-dom": "^18.2.25",
47
+ "awilix": "^8.0.1",
48
+ "pg": "^8.13.0",
49
+ "prop-types": "^15.8.1",
50
+ "react": "^18.2.0",
51
+ "react-dom": "^18.2.0",
52
+ "ts-node": "^10.9.2",
53
+ "typescript": "^5.6.2",
54
+ "vite": "^5.2.11",
55
+ "yalc": "^1.0.0-pre.53"
56
+ },
57
+ "peerDependencies": {
58
+ "@medusajs/admin-sdk": "2.10.0",
59
+ "@medusajs/cli": "2.10.0",
60
+ "@medusajs/framework": "2.10.0",
61
+ "@medusajs/icons": "^2.10.0",
62
+ "@medusajs/medusa": "2.10.0",
63
+ "@medusajs/test-utils": "2.10.0",
64
+ "@medusajs/ui": "4.0.3",
65
+ "@mikro-orm/cli": "6.4.3",
66
+ "@mikro-orm/core": "6.4.3",
67
+ "@mikro-orm/knex": "6.4.3",
68
+ "@mikro-orm/migrations": "6.4.3",
69
+ "@mikro-orm/postgresql": "6.4.3",
70
+ "awilix": "^8.0.1",
71
+ "pg": "^8.13.0"
72
+ },
73
+ "engines": {
74
+ "node": ">=20"
75
+ },
76
+ "dependencies": {
77
+ "@google-cloud/storage": "^7.16.0"
78
+ }
79
+ }