picgo-plugin-s3 1.1.3 → 1.2.0
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/.eslintrc +21 -0
- package/README.md +13 -11
- package/dist/config.d.ts +13 -0
- package/dist/config.js +2 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +75 -57
- package/dist/uploader.d.ts +5 -4
- package/dist/uploader.js +44 -29
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +21 -23
- package/package.json +9 -11
package/.eslintrc
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"parser": "@typescript-eslint/parser",
|
|
3
|
+
"extends": [
|
|
4
|
+
"eslint:recommended",
|
|
5
|
+
"plugin:@typescript-eslint/recommended",
|
|
6
|
+
"prettier"
|
|
7
|
+
],
|
|
8
|
+
"plugins": ["prettier", "@typescript-eslint"],
|
|
9
|
+
"env": {
|
|
10
|
+
"es6": true,
|
|
11
|
+
"node": true
|
|
12
|
+
},
|
|
13
|
+
"rules": {
|
|
14
|
+
"prettier/prettier": [
|
|
15
|
+
"error",
|
|
16
|
+
{
|
|
17
|
+
"semi": false
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
}
|
|
21
|
+
}
|
package/README.md
CHANGED
|
@@ -19,17 +19,19 @@ GUI 直接搜索 _S3_ 下载即可,Core 版执行 `picgo add s3` 安装。
|
|
|
19
19
|
picgo set uploader aws-s3
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
| Key
|
|
23
|
-
|
|
|
24
|
-
| `accessKeyID`
|
|
25
|
-
| `secretAccessKey`
|
|
26
|
-
| `bucketName`
|
|
27
|
-
| `uploadPath`
|
|
28
|
-
| `urlPrefix`
|
|
29
|
-
| `endpoint`
|
|
30
|
-
| `region`
|
|
31
|
-
| `pathStyleAccess`
|
|
32
|
-
| `
|
|
22
|
+
| Key | 说明 | 例子 |
|
|
23
|
+
| -------------------- | ----------------------------------------------------------------------- | -------------------------------------------------------- |
|
|
24
|
+
| `accessKeyID` | AWS 凭证 ID | |
|
|
25
|
+
| `secretAccessKey` | AWS 凭证密钥 | |
|
|
26
|
+
| `bucketName` | S3 桶名称 | `gallery` |
|
|
27
|
+
| `uploadPath` | 上传路径 | `{year}/{month}/{fullName}` |
|
|
28
|
+
| `urlPrefix` | 最终生成图片 URL 的自定义前缀 | `https://img.example.com/my-blog/` |
|
|
29
|
+
| `endpoint` | 指定自定义终端节点 | `s3.us-west-2.amazonaws.com` |
|
|
30
|
+
| `region` | 指定执行服务请求的区域 | `us-west-1` |
|
|
31
|
+
| `pathStyleAccess` | 是否启用 S3 Path style | 默认为 `false`,使用 minio 请设置为 `true` |
|
|
32
|
+
| `rejectUnauthorized` | 是否拒绝无效 TLS 证书连接 | 默认为 `true`,如上传失败日志显示证书问题可设置为`false` |
|
|
33
|
+
| `bucketEndpoint` | 提供的 Endpoint 是否针对单个存储桶(如果它针对根 API 端点,则为 false) | 默认为 `false` |
|
|
34
|
+
| `acl` | 访问控制列表,上传资源的访问策略 | 默认为 `public-read` |
|
|
33
35
|
|
|
34
36
|
**上传路径支持 payload:**
|
|
35
37
|
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface IS3UserConfig {
|
|
2
|
+
accessKeyID: string;
|
|
3
|
+
secretAccessKey: string;
|
|
4
|
+
bucketName: string;
|
|
5
|
+
uploadPath: string;
|
|
6
|
+
region?: string;
|
|
7
|
+
endpoint?: string;
|
|
8
|
+
urlPrefix?: string;
|
|
9
|
+
pathStyleAccess?: boolean;
|
|
10
|
+
rejectUnauthorized?: boolean;
|
|
11
|
+
bucketEndpoint?: boolean;
|
|
12
|
+
acl?: string;
|
|
13
|
+
}
|
package/dist/config.js
ADDED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -7,108 +7,126 @@ const utils_1 = require("./utils");
|
|
|
7
7
|
module.exports = (ctx) => {
|
|
8
8
|
const config = (ctx) => {
|
|
9
9
|
const defaultConfig = {
|
|
10
|
-
accessKeyID:
|
|
11
|
-
secretAccessKey:
|
|
12
|
-
bucketName:
|
|
13
|
-
uploadPath:
|
|
10
|
+
accessKeyID: "",
|
|
11
|
+
secretAccessKey: "",
|
|
12
|
+
bucketName: "",
|
|
13
|
+
uploadPath: "{year}/{month}/{md5}.{extName}",
|
|
14
14
|
pathStyleAccess: false,
|
|
15
|
-
|
|
15
|
+
rejectUnauthorized: true,
|
|
16
|
+
bucketEndpoint: false,
|
|
17
|
+
acl: "public-read",
|
|
16
18
|
};
|
|
17
|
-
let userConfig = ctx.getConfig(
|
|
19
|
+
let userConfig = ctx.getConfig("picBed.aws-s3");
|
|
18
20
|
userConfig = Object.assign(Object.assign({}, defaultConfig), (userConfig || {}));
|
|
19
21
|
return [
|
|
20
22
|
{
|
|
21
|
-
name:
|
|
22
|
-
type:
|
|
23
|
+
name: "accessKeyID",
|
|
24
|
+
type: "input",
|
|
23
25
|
default: userConfig.accessKeyID,
|
|
24
26
|
required: true,
|
|
25
|
-
message:
|
|
26
|
-
alias:
|
|
27
|
+
message: "access key id",
|
|
28
|
+
alias: "应用密钥 ID",
|
|
27
29
|
},
|
|
28
30
|
{
|
|
29
|
-
name:
|
|
30
|
-
type:
|
|
31
|
+
name: "secretAccessKey",
|
|
32
|
+
type: "password",
|
|
31
33
|
default: userConfig.secretAccessKey,
|
|
32
34
|
required: true,
|
|
33
|
-
message:
|
|
34
|
-
alias:
|
|
35
|
+
message: "secret access key",
|
|
36
|
+
alias: "应用密钥",
|
|
35
37
|
},
|
|
36
38
|
{
|
|
37
|
-
name:
|
|
38
|
-
type:
|
|
39
|
+
name: "bucketName",
|
|
40
|
+
type: "input",
|
|
39
41
|
default: userConfig.bucketName,
|
|
40
42
|
required: true,
|
|
41
|
-
alias:
|
|
43
|
+
alias: "桶",
|
|
42
44
|
},
|
|
43
45
|
{
|
|
44
|
-
name:
|
|
45
|
-
type:
|
|
46
|
+
name: "uploadPath",
|
|
47
|
+
type: "input",
|
|
46
48
|
default: userConfig.uploadPath,
|
|
47
49
|
required: true,
|
|
48
|
-
alias:
|
|
50
|
+
alias: "文件路径",
|
|
49
51
|
},
|
|
50
52
|
{
|
|
51
|
-
name:
|
|
52
|
-
type:
|
|
53
|
+
name: "acl",
|
|
54
|
+
type: "input",
|
|
53
55
|
default: userConfig.acl,
|
|
54
|
-
message:
|
|
56
|
+
message: "文件访问权限",
|
|
55
57
|
required: true,
|
|
56
|
-
alias:
|
|
58
|
+
alias: "权限",
|
|
57
59
|
},
|
|
58
60
|
{
|
|
59
|
-
name:
|
|
60
|
-
type:
|
|
61
|
+
name: "region",
|
|
62
|
+
type: "input",
|
|
61
63
|
default: userConfig.region,
|
|
62
64
|
required: false,
|
|
63
|
-
alias:
|
|
65
|
+
alias: "地区",
|
|
64
66
|
},
|
|
65
67
|
{
|
|
66
|
-
name:
|
|
67
|
-
type:
|
|
68
|
+
name: "endpoint",
|
|
69
|
+
type: "input",
|
|
68
70
|
default: userConfig.endpoint,
|
|
69
71
|
required: false,
|
|
70
|
-
alias:
|
|
72
|
+
alias: "自定义节点",
|
|
71
73
|
},
|
|
72
74
|
{
|
|
73
|
-
name:
|
|
74
|
-
type:
|
|
75
|
+
name: "urlPrefix",
|
|
76
|
+
type: "input",
|
|
75
77
|
default: userConfig.urlPrefix,
|
|
76
|
-
message:
|
|
78
|
+
message: "https://img.example.com/bucket-name/",
|
|
77
79
|
required: false,
|
|
78
|
-
alias:
|
|
80
|
+
alias: "自定义域名",
|
|
79
81
|
},
|
|
80
82
|
{
|
|
81
|
-
name:
|
|
82
|
-
type:
|
|
83
|
+
name: "pathStyleAccess",
|
|
84
|
+
type: "confirm",
|
|
83
85
|
default: userConfig.pathStyleAccess || false,
|
|
84
|
-
message:
|
|
86
|
+
message: "enable path-style-access or not",
|
|
85
87
|
required: false,
|
|
86
|
-
alias:
|
|
88
|
+
alias: "PathStyleAccess",
|
|
87
89
|
},
|
|
88
90
|
{
|
|
89
|
-
name:
|
|
90
|
-
type:
|
|
91
|
-
default: userConfig.
|
|
92
|
-
message:
|
|
91
|
+
name: "rejectUnauthorized",
|
|
92
|
+
type: "confirm",
|
|
93
|
+
default: userConfig.rejectUnauthorized || true,
|
|
94
|
+
message: "是否拒绝无效TLS证书连接",
|
|
93
95
|
required: false,
|
|
94
|
-
alias:
|
|
95
|
-
}
|
|
96
|
+
alias: "rejectUnauthorized",
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
name: "bucketEndpoint",
|
|
100
|
+
type: "confirm",
|
|
101
|
+
default: userConfig.bucketEndpoint || false,
|
|
102
|
+
message: "提供的Endpoint是否针对单个存储桶(如果它针对根 API 端点,则为 false)",
|
|
103
|
+
required: false,
|
|
104
|
+
alias: "bucketEndpoint",
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
name: "acl",
|
|
108
|
+
type: "input",
|
|
109
|
+
default: userConfig.acl || "public-read",
|
|
110
|
+
message: "上传资源的访问策略",
|
|
111
|
+
required: false,
|
|
112
|
+
alias: "ACL 访问控制列表",
|
|
113
|
+
},
|
|
96
114
|
];
|
|
97
115
|
};
|
|
98
116
|
const handle = async (ctx) => {
|
|
99
|
-
|
|
117
|
+
const userConfig = ctx.getConfig("picBed.aws-s3");
|
|
100
118
|
if (!userConfig) {
|
|
101
119
|
throw new Error("Can't find amazon s3 uploader config");
|
|
102
120
|
}
|
|
103
121
|
if (userConfig.urlPrefix) {
|
|
104
|
-
userConfig.urlPrefix = userConfig.urlPrefix.replace(/\/?$/,
|
|
122
|
+
userConfig.urlPrefix = userConfig.urlPrefix.replace(/\/?$/, "");
|
|
105
123
|
}
|
|
106
|
-
const client = uploader_1.default.createS3Client(userConfig
|
|
124
|
+
const client = uploader_1.default.createS3Client(userConfig);
|
|
107
125
|
const output = ctx.output;
|
|
108
|
-
const tasks = output.map((item, idx) => uploader_1.default.createUploadTask(client, userConfig.bucketName, utils_1.formatPath(item, userConfig.uploadPath), item, idx, userConfig.acl));
|
|
126
|
+
const tasks = output.map((item, idx) => uploader_1.default.createUploadTask(client, userConfig.bucketName, (0, utils_1.formatPath)(item, userConfig.uploadPath), item, idx, userConfig.acl));
|
|
109
127
|
try {
|
|
110
128
|
const results = await Promise.all(tasks);
|
|
111
|
-
for (
|
|
129
|
+
for (const result of results) {
|
|
112
130
|
const { index, url, imgURL } = result;
|
|
113
131
|
delete output[index].buffer;
|
|
114
132
|
delete output[index].base64Image;
|
|
@@ -122,24 +140,24 @@ module.exports = (ctx) => {
|
|
|
122
140
|
return ctx;
|
|
123
141
|
}
|
|
124
142
|
catch (err) {
|
|
125
|
-
ctx.log.error(
|
|
143
|
+
ctx.log.error("上传到 Amazon S3 发生错误,请检查配置是否正确");
|
|
126
144
|
ctx.log.error(err);
|
|
127
|
-
ctx.emit(
|
|
128
|
-
title:
|
|
129
|
-
body:
|
|
130
|
-
text:
|
|
145
|
+
ctx.emit("notification", {
|
|
146
|
+
title: "Amazon S3 上传错误",
|
|
147
|
+
body: "请检查配置是否正确",
|
|
148
|
+
text: "",
|
|
131
149
|
});
|
|
132
150
|
throw err;
|
|
133
151
|
}
|
|
134
152
|
};
|
|
135
153
|
const register = () => {
|
|
136
|
-
ctx.helper.uploader.register(
|
|
154
|
+
ctx.helper.uploader.register("aws-s3", {
|
|
137
155
|
handle,
|
|
138
156
|
config,
|
|
139
|
-
name:
|
|
157
|
+
name: "Amazon S3",
|
|
140
158
|
});
|
|
141
159
|
};
|
|
142
160
|
return {
|
|
143
|
-
register
|
|
161
|
+
register,
|
|
144
162
|
};
|
|
145
163
|
};
|
package/dist/uploader.d.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { IImgInfo } from
|
|
1
|
+
import S3 from "aws-sdk/clients/s3";
|
|
2
|
+
import { IImgInfo } from "picgo/dist/src/types";
|
|
3
|
+
import { IS3UserConfig } from "./config";
|
|
3
4
|
export interface IUploadResult {
|
|
4
5
|
url: string;
|
|
5
6
|
imgURL: string;
|
|
6
7
|
index: number;
|
|
7
8
|
}
|
|
8
|
-
declare function createS3Client(
|
|
9
|
-
declare function createUploadTask(s3:
|
|
9
|
+
declare function createS3Client(opts: IS3UserConfig): S3;
|
|
10
|
+
declare function createUploadTask(s3: S3, bucketName: string, path: string, item: IImgInfo, index: number, acl: string): Promise<IUploadResult>;
|
|
10
11
|
declare const _default: {
|
|
11
12
|
createS3Client: typeof createS3Client;
|
|
12
13
|
createUploadTask: typeof createUploadTask;
|
package/dist/uploader.js
CHANGED
|
@@ -3,45 +3,60 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const
|
|
6
|
+
const s3_1 = __importDefault(require("aws-sdk/clients/s3"));
|
|
7
7
|
const utils_1 = require("./utils");
|
|
8
|
-
function createS3Client(
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
8
|
+
function createS3Client(opts) {
|
|
9
|
+
const endpointURL = new URL(opts.endpoint);
|
|
10
|
+
const sslEnabled = endpointURL.protocol === "https";
|
|
11
|
+
const http = sslEnabled ? require("https") : require("http");
|
|
12
|
+
const s3 = new s3_1.default({
|
|
13
|
+
region: opts.region,
|
|
14
|
+
endpoint: opts.endpoint,
|
|
15
|
+
accessKeyId: opts.accessKeyID,
|
|
16
|
+
secretAccessKey: opts.secretAccessKey,
|
|
17
|
+
s3ForcePathStyle: opts.pathStyleAccess,
|
|
18
|
+
s3BucketEndpoint: opts.bucketEndpoint,
|
|
19
|
+
sslEnabled: sslEnabled,
|
|
20
|
+
httpOptions: {
|
|
21
|
+
agent: new http.Agent({
|
|
22
|
+
rejectUnauthorized: opts.rejectUnauthorized,
|
|
23
|
+
}),
|
|
24
|
+
},
|
|
15
25
|
});
|
|
16
26
|
return s3;
|
|
17
27
|
}
|
|
18
28
|
function createUploadTask(s3, bucketName, path, item, index, acl) {
|
|
19
|
-
return new Promise(
|
|
29
|
+
return new Promise((resolve, reject) => {
|
|
20
30
|
if (!item.buffer && !item.base64Image) {
|
|
21
|
-
reject(new Error(
|
|
31
|
+
reject(new Error("undefined image"));
|
|
22
32
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
.
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
33
|
+
(0, utils_1.extractInfo)(item)
|
|
34
|
+
.then(({ body, contentType, contentEncoding }) => {
|
|
35
|
+
const opts = {
|
|
36
|
+
Key: path,
|
|
37
|
+
Bucket: bucketName,
|
|
38
|
+
ACL: acl,
|
|
39
|
+
Body: body,
|
|
40
|
+
ContentType: contentType,
|
|
41
|
+
ContentEncoding: contentEncoding,
|
|
42
|
+
};
|
|
43
|
+
s3.upload(opts)
|
|
44
|
+
.promise()
|
|
45
|
+
.then((result) => {
|
|
46
|
+
resolve({
|
|
47
|
+
url: result.Location,
|
|
48
|
+
imgURL: result.Key,
|
|
49
|
+
index,
|
|
50
|
+
});
|
|
51
|
+
})
|
|
52
|
+
.catch((err) => reject(err));
|
|
40
53
|
})
|
|
41
|
-
.catch((err) =>
|
|
54
|
+
.catch((err) => {
|
|
55
|
+
reject(err);
|
|
56
|
+
});
|
|
42
57
|
});
|
|
43
58
|
}
|
|
44
59
|
exports.default = {
|
|
45
60
|
createS3Client,
|
|
46
|
-
createUploadTask
|
|
61
|
+
createUploadTask,
|
|
47
62
|
};
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import { IImgInfo } from
|
|
2
|
+
import { IImgInfo } from "picgo/dist/src/types";
|
|
3
3
|
export declare function formatPath(info: IImgInfo, format?: string): string;
|
|
4
4
|
export declare function extractInfo(info: IImgInfo): Promise<{
|
|
5
5
|
body?: Buffer;
|
package/dist/utils.js
CHANGED
|
@@ -29,36 +29,34 @@ class FileNameGenerator {
|
|
|
29
29
|
return this.info.fileName;
|
|
30
30
|
}
|
|
31
31
|
fileName() {
|
|
32
|
-
return this.info.fileName.replace(this.info.extname,
|
|
32
|
+
return this.info.fileName.replace(this.info.extname, "");
|
|
33
33
|
}
|
|
34
34
|
extName() {
|
|
35
|
-
return this.info.extname.replace(
|
|
35
|
+
return this.info.extname.replace(".", "");
|
|
36
36
|
}
|
|
37
37
|
md5() {
|
|
38
|
-
return crypto_1.default.createHash(
|
|
38
|
+
return crypto_1.default.createHash("md5").update(this.imgBuffer()).digest("hex");
|
|
39
39
|
}
|
|
40
40
|
sha1() {
|
|
41
|
-
return crypto_1.default.createHash(
|
|
41
|
+
return crypto_1.default.createHash("sha1").update(this.imgBuffer()).digest("hex");
|
|
42
42
|
}
|
|
43
43
|
sha256() {
|
|
44
|
-
return crypto_1.default.createHash(
|
|
44
|
+
return crypto_1.default.createHash("sha256").update(this.imgBuffer()).digest("hex");
|
|
45
45
|
}
|
|
46
46
|
imgBuffer() {
|
|
47
|
-
return this.info.base64Image
|
|
48
|
-
? this.info.base64Image
|
|
49
|
-
: this.info.buffer;
|
|
47
|
+
return this.info.base64Image ? this.info.base64Image : this.info.buffer;
|
|
50
48
|
}
|
|
51
49
|
}
|
|
52
50
|
FileNameGenerator.fields = [
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
51
|
+
"year",
|
|
52
|
+
"month",
|
|
53
|
+
"day",
|
|
54
|
+
"fullName",
|
|
55
|
+
"fileName",
|
|
56
|
+
"extName",
|
|
57
|
+
"md5",
|
|
58
|
+
"sha1",
|
|
59
|
+
"sha256",
|
|
62
60
|
];
|
|
63
61
|
function formatPath(info, format) {
|
|
64
62
|
if (!format) {
|
|
@@ -66,8 +64,8 @@ function formatPath(info, format) {
|
|
|
66
64
|
}
|
|
67
65
|
const fileNameGenerator = new FileNameGenerator(info);
|
|
68
66
|
let formatPath = format;
|
|
69
|
-
for (
|
|
70
|
-
const re = new RegExp(`{${key}}`,
|
|
67
|
+
for (const key of FileNameGenerator.fields) {
|
|
68
|
+
const re = new RegExp(`{${key}}`, "g");
|
|
71
69
|
formatPath = formatPath.replace(re, fileNameGenerator[key]());
|
|
72
70
|
}
|
|
73
71
|
return formatPath;
|
|
@@ -75,12 +73,12 @@ function formatPath(info, format) {
|
|
|
75
73
|
exports.formatPath = formatPath;
|
|
76
74
|
async function extractInfo(info) {
|
|
77
75
|
var _a;
|
|
78
|
-
|
|
76
|
+
const result = {};
|
|
79
77
|
if (info.base64Image) {
|
|
80
|
-
const body = info.base64Image.replace(/^data:[/\w]+;base64,/,
|
|
78
|
+
const body = info.base64Image.replace(/^data:[/\w]+;base64,/, "");
|
|
81
79
|
result.contentType = (_a = info.base64Image.match(/[^:]\w+\/[\w-+\d.]+(?=;|,)/)) === null || _a === void 0 ? void 0 : _a[0];
|
|
82
|
-
result.body = Buffer.from(body,
|
|
83
|
-
result.contentEncoding =
|
|
80
|
+
result.body = Buffer.from(body, "base64");
|
|
81
|
+
result.contentEncoding = "base64";
|
|
84
82
|
}
|
|
85
83
|
else {
|
|
86
84
|
if (info.extname) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "picgo-plugin-s3",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "picgo amazon s3 uploader",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"publishConfig": {
|
|
@@ -27,17 +27,15 @@
|
|
|
27
27
|
"author": "WayJam So",
|
|
28
28
|
"license": "MIT",
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@types/node": "^
|
|
31
|
-
"eslint": "^5.
|
|
32
|
-
"eslint
|
|
33
|
-
"eslint
|
|
34
|
-
"eslint-
|
|
35
|
-
"eslint-plugin-
|
|
36
|
-
"eslint-plugin-standard": "^3.1.0",
|
|
30
|
+
"@types/node": "^18.7.23",
|
|
31
|
+
"@typescript-eslint/eslint-plugin": "^5.38.1",
|
|
32
|
+
"@typescript-eslint/parser": "^5.38.1",
|
|
33
|
+
"eslint": "^8.25.0",
|
|
34
|
+
"eslint-config-prettier": "^8.5.0",
|
|
35
|
+
"eslint-plugin-prettier": "^4.2.1",
|
|
37
36
|
"picgo": "^1.4.0 >1.4.16",
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"typescript": "^3.7.3"
|
|
37
|
+
"prettier": "^2.7.1",
|
|
38
|
+
"typescript": "^4.8.4"
|
|
41
39
|
},
|
|
42
40
|
"dependencies": {
|
|
43
41
|
"aws-sdk": "^2.839.0",
|