importer-storage 1.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.
package/LICENSE.md ADDED
@@ -0,0 +1,12 @@
1
+ MIT License
2
+
3
+ Copyright (c) vonpoland
4
+
5
+ Permission is hereby granted, free of charge, to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, subject to the following conditions:
6
+
7
+ 1. This Software may be used in private, non-commercial projects without restriction.
8
+ 2. For any commercial use, including but not limited to the use of the Software in paid projects, software as a service (SaaS), or any other form of commercial distribution, prior written permission must be obtained from the author.
9
+
10
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11
+
12
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,50 @@
1
+ # React + TypeScript + Vite
2
+
3
+ This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
4
+
5
+ Currently, two official plugins are available:
6
+
7
+ - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
8
+ - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
9
+
10
+ ## Expanding the ESLint configuration
11
+
12
+ If you are developing a production application, we recommend updating the configuration to enable type aware lint rules:
13
+
14
+ - Configure the top-level `parserOptions` property like this:
15
+
16
+ ```js
17
+ export default tseslint.config({
18
+ languageOptions: {
19
+ // other options...
20
+ parserOptions: {
21
+ project: ["./tsconfig.node.json", "./tsconfig.app.json"],
22
+ tsconfigRootDir: import.meta.dirname,
23
+ },
24
+ },
25
+ });
26
+ ```
27
+
28
+ - Replace `tseslint.configs.recommended` to `tseslint.configs.recommendedTypeChecked` or `tseslint.configs.strictTypeChecked`
29
+ - Optionally add `...tseslint.configs.stylisticTypeChecked`
30
+ - Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and update the config:
31
+
32
+ ```js
33
+ // eslint.config.js
34
+ import react from "eslint-plugin-react";
35
+
36
+ export default tseslint.config({
37
+ // Set the react version
38
+ settings: { react: { version: "18.3" } },
39
+ plugins: {
40
+ // Add the react plugin
41
+ react,
42
+ },
43
+ rules: {
44
+ // other rules...
45
+ // Enable its recommended rules
46
+ ...react.configs.recommended.rules,
47
+ ...react.configs["jsx-runtime"].rules,
48
+ },
49
+ });
50
+ ```
package/dist/index.cjs ADDED
@@ -0,0 +1,163 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var __async = (__this, __arguments, generator) => {
30
+ return new Promise((resolve, reject) => {
31
+ var fulfilled = (value) => {
32
+ try {
33
+ step(generator.next(value));
34
+ } catch (e) {
35
+ reject(e);
36
+ }
37
+ };
38
+ var rejected = (value) => {
39
+ try {
40
+ step(generator.throw(value));
41
+ } catch (e) {
42
+ reject(e);
43
+ }
44
+ };
45
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
46
+ step((generator = generator.apply(__this, __arguments)).next());
47
+ });
48
+ };
49
+
50
+ // src/index.ts
51
+ var index_exports = {};
52
+ __export(index_exports, {
53
+ Storage: () => Storage
54
+ });
55
+ module.exports = __toCommonJS(index_exports);
56
+
57
+ // src/logic/storage.ts
58
+ var import_client_s3 = require("@aws-sdk/client-s3");
59
+ var import_fs = require("fs");
60
+ var import_dotenv = require("dotenv");
61
+ var import_axios = __toESM(require("axios"), 1);
62
+ (0, import_dotenv.config)();
63
+ if (!process.env.AWS_ACCESS_KEY_ID) {
64
+ throw new Error("'AWS_ACCESS_KEY_ID' not set");
65
+ }
66
+ if (!process.env.AWS_ACCESS_KEY) {
67
+ throw new Error("'AWS_ACCESS_KEY' not set");
68
+ }
69
+ function extractFileInfo(filePath) {
70
+ const parts = filePath.split("/");
71
+ const key = parts[parts.length - 1];
72
+ const extMatch = key.match(/\.([^.]+)$/);
73
+ const extension = extMatch ? extMatch[1].toLowerCase() : null;
74
+ return { key, extension: extension || "jpg" };
75
+ }
76
+ var s3 = new import_client_s3.S3Client({
77
+ region: process.env.AWS_REGION,
78
+ credentials: {
79
+ accessKeyId: process.env.AWS_ACCESS_KEY_ID,
80
+ secretAccessKey: process.env.AWS_ACCESS_KEY
81
+ }
82
+ });
83
+ var BUCKET_NAME = process.env.AWS_BUCKET_NAME;
84
+ if (!BUCKET_NAME) {
85
+ throw new Error("'AWS_BUCKET_NAME' name not set");
86
+ }
87
+ function isHttp(url) {
88
+ return url.startsWith("http://") || url.startsWith("https://");
89
+ }
90
+ var S3Storage = class {
91
+ saveFiles(keys, options) {
92
+ return __async(this, null, function* () {
93
+ const urls = [];
94
+ for (const { key, filePath } of keys) {
95
+ const s3Key = `${options.savePath}/${key}`;
96
+ let stream;
97
+ if (isHttp(filePath)) {
98
+ stream = yield import_axios.default.get(filePath, {
99
+ responseType: "stream"
100
+ });
101
+ }
102
+ stream = (0, import_fs.createReadStream)(filePath);
103
+ const tagString = options.tags.map(
104
+ (tag) => `${encodeURIComponent(tag.split(":")[0])}=${encodeURIComponent(tag.split(":")[1])}`
105
+ ).join("&");
106
+ const command = new import_client_s3.PutObjectCommand({
107
+ Body: stream,
108
+ Bucket: BUCKET_NAME,
109
+ Key: s3Key,
110
+ Tagging: tagString || void 0,
111
+ ContentType: `image/${extractFileInfo(key).extension}`,
112
+ ContentDisposition: "inline"
113
+ });
114
+ yield s3.send(command);
115
+ urls.push(
116
+ `https://${BUCKET_NAME}.s3.${process.env.AWS_REGION}.amazonaws.com/${s3Key}`
117
+ );
118
+ }
119
+ return { urls: urls.join(",") };
120
+ });
121
+ }
122
+ removeTag(savePath, tags) {
123
+ return __async(this, null, function* () {
124
+ var _a;
125
+ const list = yield s3.send(
126
+ new import_client_s3.ListObjectsCommand({
127
+ Bucket: BUCKET_NAME,
128
+ Prefix: savePath + "/",
129
+ MaxKeys: 1e3
130
+ })
131
+ );
132
+ if (!list.Contents) return;
133
+ for (const obj of list.Contents) {
134
+ if (!obj.Key) continue;
135
+ const currentTags = yield s3.send(
136
+ new import_client_s3.GetObjectTaggingCommand({
137
+ Bucket: BUCKET_NAME,
138
+ Key: obj.Key
139
+ })
140
+ );
141
+ const filteredTags = ((_a = currentTags.TagSet) == null ? void 0 : _a.filter(
142
+ (t) => !tags.includes(`${t.Key}:${t.Value}`)
143
+ )) || [];
144
+ yield s3.send(
145
+ new import_client_s3.PutObjectTaggingCommand({
146
+ Bucket: BUCKET_NAME,
147
+ Key: obj.Key,
148
+ Tagging: { TagSet: filteredTags }
149
+ })
150
+ );
151
+ }
152
+ });
153
+ }
154
+ };
155
+
156
+ // src/index.ts
157
+ var Storage = {
158
+ S3Storage
159
+ };
160
+ // Annotate the CommonJS export names for ESM import in node:
161
+ 0 && (module.exports = {
162
+ Storage
163
+ });
@@ -0,0 +1,33 @@
1
+ type StorageTag = "delete:60d";
2
+
3
+ interface IStorage {
4
+ saveFiles(keys: Array<{
5
+ key: string;
6
+ filePath: string;
7
+ }>, options: {
8
+ tags: Array<StorageTag>;
9
+ savePath: string;
10
+ }): Promise<{
11
+ urls: string;
12
+ }>;
13
+ removeTag(savePath: string, tags: Array<StorageTag>): Promise<void>;
14
+ }
15
+
16
+ declare class S3Storage implements IStorage {
17
+ saveFiles(keys: Array<{
18
+ key: string;
19
+ filePath: string;
20
+ }>, options: {
21
+ tags: Array<StorageTag>;
22
+ savePath: string;
23
+ }): Promise<{
24
+ urls: string;
25
+ }>;
26
+ removeTag(savePath: string, tags: Array<StorageTag>): Promise<void>;
27
+ }
28
+
29
+ declare const Storage: {
30
+ S3Storage: typeof S3Storage;
31
+ };
32
+
33
+ export { Storage };
@@ -0,0 +1,33 @@
1
+ type StorageTag = "delete:60d";
2
+
3
+ interface IStorage {
4
+ saveFiles(keys: Array<{
5
+ key: string;
6
+ filePath: string;
7
+ }>, options: {
8
+ tags: Array<StorageTag>;
9
+ savePath: string;
10
+ }): Promise<{
11
+ urls: string;
12
+ }>;
13
+ removeTag(savePath: string, tags: Array<StorageTag>): Promise<void>;
14
+ }
15
+
16
+ declare class S3Storage implements IStorage {
17
+ saveFiles(keys: Array<{
18
+ key: string;
19
+ filePath: string;
20
+ }>, options: {
21
+ tags: Array<StorageTag>;
22
+ savePath: string;
23
+ }): Promise<{
24
+ urls: string;
25
+ }>;
26
+ removeTag(savePath: string, tags: Array<StorageTag>): Promise<void>;
27
+ }
28
+
29
+ declare const Storage: {
30
+ S3Storage: typeof S3Storage;
31
+ };
32
+
33
+ export { Storage };