picgo-plugin-s3 1.4.1 → 1.5.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/README.md +122 -97
- package/dist/index.js +1 -0
- package/dist/utils.d.ts +2 -1
- package/dist/utils.js +30 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,129 +1,154 @@
|
|
|
1
|
-
|
|
2
1
|
## picgo-plugin-s3
|
|
3
2
|
|
|
4
|
-

|
|
5
|
-

|
|
3
|
+
[](https://github.com/wayjam/picgo-plugin-s3/actions/workflows/publish.yaml)
|
|
4
|
+
[](https://github.com/wayjam/picgo-plugin-s3/blob/main/LICENSE)
|
|
6
5
|
[](https://www.npmjs.com/package/picgo-plugin-s3)
|
|
7
6
|
|
|
8
7
|
[PicGo](https://github.com/PicGo/PicGo-Core) Amazon S3 上传插件。
|
|
9
8
|
|
|
10
|
-
- 支持 Amazon S3
|
|
11
|
-
- 支持
|
|
12
|
-
- 支持 MinIO
|
|
9
|
+
- 支持 Amazon S3 与其他兼容 S3 API 的云存储 (例如 Backblaze B2)。
|
|
10
|
+
- 支持 PicGo GUI。
|
|
11
|
+
- 支持 MinIO。
|
|
12
|
+
|
|
13
|
+
### 安装 (Installation)
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
GUI 用户可直接在插件市场搜索 `s3` 并下载。
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
Core 用户可执行 `picgo add s3` 命令安装。
|
|
17
18
|
|
|
18
|
-
### 配置 Configuration
|
|
19
|
+
### 配置 (Configuration)
|
|
19
20
|
|
|
20
21
|
```sh
|
|
21
|
-
picgo set uploader
|
|
22
|
+
picgo set uploader s3
|
|
22
23
|
```
|
|
23
24
|
|
|
24
|
-
| Key
|
|
25
|
-
|
|
|
26
|
-
| `accessKeyID`
|
|
27
|
-
| `secretAccessKey`
|
|
28
|
-
| `bucketName`
|
|
29
|
-
| `uploadPath`
|
|
30
|
-
| `endpoint`
|
|
31
|
-
| `proxy`
|
|
32
|
-
| `region`
|
|
33
|
-
| `pathStyleAccess`
|
|
34
|
-
| `rejectUnauthorized
|
|
35
|
-
| `acl`
|
|
36
|
-
| `outputURLPattern`
|
|
37
|
-
| `urlPrefix`
|
|
38
|
-
| `urlSuffix`
|
|
39
|
-
| `disableBucketPrefixToURL` |
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
|
48
|
-
|
|
|
49
|
-
| `{
|
|
50
|
-
| `{
|
|
51
|
-
| `{
|
|
52
|
-
| `{
|
|
53
|
-
| `{
|
|
54
|
-
| `{
|
|
55
|
-
| `{
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
|
64
|
-
|
|
|
65
|
-
| `{
|
|
66
|
-
| `{
|
|
67
|
-
| `{
|
|
68
|
-
| `{
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
|
81
|
-
|
|
|
82
|
-
| `{
|
|
83
|
-
| `{
|
|
84
|
-
| `{
|
|
85
|
-
| `{
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
25
|
+
| Key | 说明 | 示例 |
|
|
26
|
+
| :--- | :--- | :--- |
|
|
27
|
+
| `accessKeyID` | AWS 凭证 ID。 | |
|
|
28
|
+
| `secretAccessKey` | AWS 凭证密钥。 | |
|
|
29
|
+
| `bucketName` | S3 桶名称。 | `gallery` |
|
|
30
|
+
| `uploadPath` | 上传路径,详细配置请查看以下说明。 | `{year}/{month}/{fullName}` |
|
|
31
|
+
| `endpoint` | 指定自定义终端节点。 | `s3.us-west-2.amazonaws.com` |
|
|
32
|
+
| `proxy` | 代理地址,支持 http 代理。 | `http://127.0.0.1:1080` |
|
|
33
|
+
| `region` | 指定执行服务请求的区域。 | `us-west-1` |
|
|
34
|
+
| `pathStyleAccess` | 是否启用 S3 Path style 访问模式。<br>例如 `https://s3.amazonaws.com/<bucketName>/<key>`。<br>使用 MinIO 时请设置为 `true`。 | 默认为 `false` |
|
|
35
|
+
| `rejectUnauthorized`| 是否拒绝无效的 TLS 证书连接。<br>如上传失败日志显示证书问题可设置为 `false`。 | 默认为 `true` |
|
|
36
|
+
| `acl` | 访问控制列表 (ACL),用于设置资源的访问策略。<br>可选值: `private`, `public-read`, `public-read-write`, `authenticated-read`, `aws-exec-read`, `bucket-owner-read`, `bucket-owner-full-control`。 | 默认为 `public-read` |
|
|
37
|
+
| `outputURLPattern` | 自定义输出 URL 模板,详细配置请查看以下说明。 | `{protocol}://{host}:{port}/{path}` |
|
|
38
|
+
| `urlPrefix` | **[已废弃]** 自定义 URL 前缀。请使用 `outputURLPattern`。 | `https://img.example.com/my-blog/` |
|
|
39
|
+
| `urlSuffix` | **[已废弃]** 自定义 URL 后缀。请使用 `outputURLPattern`。 | `?oxx=xxx` |
|
|
40
|
+
| `disableBucketPrefixToURL` | **[已废弃]** 禁用 URL 中的 bucket 前缀。请使用 `outputURLPattern`。 | 默认为 `false` |
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
#### 通用占位符
|
|
45
|
+
|
|
46
|
+
`uploadPath` 和 `outputURLPattern` 均支持通用占位符,插件会将其替换为实际变量。
|
|
47
|
+
|
|
48
|
+
| 占位符 | 描述 |
|
|
49
|
+
| :--- | :--- |
|
|
50
|
+
| `{year}` | 年 |
|
|
51
|
+
| `{month}` | 月 |
|
|
52
|
+
| `{day}` | 日 |
|
|
53
|
+
| `{hour}` | 时 |
|
|
54
|
+
| `{minute}` | 分 |
|
|
55
|
+
| `{second}` | 秒 |
|
|
56
|
+
| `{millisecond}` | 毫秒 |
|
|
57
|
+
| `{timestamp}` | Unix 时间戳 (秒) |
|
|
58
|
+
| `{timestampMS}` | Unix 时间戳 (毫秒) |
|
|
59
|
+
|
|
60
|
+
#### 上传路径 (`uploadPath`)
|
|
61
|
+
|
|
62
|
+
除了通用占位符外,还支持以下变量:
|
|
63
|
+
|
|
64
|
+
| 占位符 | 描述 |
|
|
65
|
+
| :--- | :--- |
|
|
66
|
+
| `{fullName}` | 完整文件名 (含扩展名) |
|
|
67
|
+
| `{fileName}` | 文件名 (不含扩展名) |
|
|
68
|
+
| `{extName}` | 扩展名 (不含 `.`) |
|
|
69
|
+
| `{md5}` | 图片 MD5 |
|
|
70
|
+
| `{sha1}` | 图片 SHA1 |
|
|
71
|
+
| `{sha256}` | 图片 SHA256 |
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
#### 自定义输出 URL 模板 (`outputURLPattern`)
|
|
76
|
+
|
|
77
|
+
此配置将替代已废弃的 `urlPrefix`、`urlSuffix` 和 `disableBucketPrefixToURL`。
|
|
78
|
+
|
|
79
|
+
除了通用占位符外,还支持以下变量:
|
|
80
|
+
|
|
81
|
+
| 占位符 | 描述 | 示例 |
|
|
82
|
+
| :--- | :--- | :--- |
|
|
83
|
+
| `{protocol}` | URL 协议 | `http` 或 `https` |
|
|
84
|
+
| `{host}` | URL 域名 | `s3.amazonaws.com` |
|
|
85
|
+
| `{port}` | URL 端口 | `80` |
|
|
86
|
+
| `{dir}` | 上传目录 | `my-bucket/2024/12` |
|
|
87
|
+
| `{file}` | 上传后的文件名 (含扩展名) | `4aa4f41e38817e5fd38ac870f40dbc70.jpg` |
|
|
88
|
+
| `{path}` | 完整路径 (`{dir}/{file}`) | `my-bucket/2024/12/4aa4f41e38817e5fd38ac870f40dbc70.jpg` |
|
|
89
|
+
| `{fileName}` | **源**文件名 (含扩展名) | `test.jpg` |
|
|
90
|
+
| `{extName}` | **源**文件扩展名 (不含 `.`) | `jpg` |
|
|
91
|
+
| `{query}` | URL 查询参数 (不含 `?`) | `height=100&width=200` |
|
|
92
|
+
| `{hash}` | URL hash (不含 `#`) | `abc` |
|
|
93
|
+
| `{bucket}` | S3 桶名 | `my-bucket` |
|
|
94
|
+
|
|
95
|
+
##### 正则替换
|
|
96
|
+
|
|
97
|
+
每个变量都支持通过正则表达式进行替换。
|
|
98
|
+
|
|
99
|
+
**语法:**
|
|
91
100
|
```
|
|
92
|
-
|
|
93
|
-
{payload:/pattern/reFlag,'replacement'}
|
|
101
|
+
{payload:/pattern/flags,'replacement'}
|
|
94
102
|
```
|
|
95
103
|
|
|
96
|
-
|
|
104
|
+
**示例:**
|
|
105
|
+
假设配置为 `{protocol}://example.com/{path:/testBucket/i,'myimage'}`,
|
|
106
|
+
并且原始 URL 为 `https://cluster.s3.example.com/testBucket/image.jpg`,
|
|
107
|
+
则最终生成的 URL 为 `https://example.com/myimage/image.jpg`。
|
|
97
108
|
|
|
98
|
-
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
#### 完整示例 (Example)
|
|
99
112
|
|
|
100
113
|
```json
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
114
|
+
{
|
|
115
|
+
"picgo-plugin-s3": {
|
|
116
|
+
"accessKeyID": "xxx",
|
|
117
|
+
"secretAccessKey": "xxxxx",
|
|
118
|
+
"bucketName": "my-bucket",
|
|
119
|
+
"uploadPath": "{year}/{md5}.{extName}",
|
|
120
|
+
"endpoint": "s3.us-west-000.backblazeb2.com",
|
|
121
|
+
"outputURLPattern": "https://img.example.com/{bucket}/{path}"
|
|
122
|
+
}
|
|
123
|
+
}
|
|
109
124
|
```
|
|
125
|
+
如果 PicGo 按以上配置,上传 `sample.png`,最终得到的图片地址可能为:`https://img.example.com/my-bucket/2021/4aa4f41e38817e5fd38ac870f40dbc70.png`。
|
|
110
126
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
## 发布 Publish
|
|
127
|
+
## 发布 (Publish)
|
|
114
128
|
|
|
115
|
-
|
|
129
|
+
执行以下任一命令,会自动更新 `package.json` 的版本号并生成一个 commit 推送到远程仓库。GitHub Action 将会自动编译、打包并发布到 NPM。
|
|
116
130
|
|
|
117
131
|
```sh
|
|
132
|
+
# 更新补丁版本 (patch)
|
|
118
133
|
npm run patch
|
|
134
|
+
|
|
135
|
+
# 更新次要版本 (minor)
|
|
119
136
|
npm run minor
|
|
137
|
+
|
|
138
|
+
# 更新主要版本 (major)
|
|
120
139
|
npm run major
|
|
121
140
|
```
|
|
122
141
|
|
|
123
|
-
##
|
|
142
|
+
## 开发 (Development)
|
|
143
|
+
|
|
144
|
+
1. Clone this repo
|
|
145
|
+
2. `npm i && npm run dev`
|
|
146
|
+
3. `cd ~/.picgo && npm install ${path_to_the_repo}`
|
|
147
|
+
|
|
148
|
+
## 贡献 (Contributing)
|
|
124
149
|
|
|
125
|
-
Pull
|
|
150
|
+
欢迎提交 Pull Request。对于重大更改,请先开一个 Issue 进行讨论。
|
|
126
151
|
|
|
127
|
-
## 许可证 License
|
|
152
|
+
## 许可证 (License)
|
|
128
153
|
|
|
129
|
-
Released under the [MIT License](https://github.com/wayjam/picgo-plugin-s3/blob/
|
|
154
|
+
Released under the [MIT License](https://github.com/wayjam/picgo-plugin-s3/blob/main/LICENSE).
|
package/dist/index.js
CHANGED
|
@@ -11,6 +11,7 @@ const upload = async (ctx) => {
|
|
|
11
11
|
const client = uploader_1.default.createS3Client(userConfig);
|
|
12
12
|
const output = ctx.output;
|
|
13
13
|
const tasks = output.map((item, idx) => {
|
|
14
|
+
item.uploadDate = new Date();
|
|
14
15
|
const fileNameGenerator = new utils_1.FileNameGenerator(item);
|
|
15
16
|
return uploader_1.default.createUploadTask({
|
|
16
17
|
client,
|
package/dist/utils.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { HttpsProxyAgent, HttpProxyAgent } from "hpagent";
|
|
|
3
3
|
import { IS3UserConfig } from "./config";
|
|
4
4
|
declare class Generateor {
|
|
5
5
|
readonly date: Date;
|
|
6
|
-
constructor();
|
|
6
|
+
constructor(date?: Date);
|
|
7
7
|
protected year(): string;
|
|
8
8
|
protected month(): string;
|
|
9
9
|
protected day(): string;
|
|
@@ -46,6 +46,7 @@ export declare class OutputURLGenerator extends Generateor {
|
|
|
46
46
|
fileName(): string;
|
|
47
47
|
extName(): string;
|
|
48
48
|
dir(): string;
|
|
49
|
+
uploadedFileName(): string;
|
|
49
50
|
originalURL(): string;
|
|
50
51
|
query(): string;
|
|
51
52
|
hash(): string;
|
package/dist/utils.js
CHANGED
|
@@ -12,8 +12,13 @@ const file_type_1 = require("file-type");
|
|
|
12
12
|
const mime_1 = __importDefault(require("mime"));
|
|
13
13
|
const hpagent_1 = require("hpagent");
|
|
14
14
|
class Generateor {
|
|
15
|
-
constructor() {
|
|
16
|
-
|
|
15
|
+
constructor(date) {
|
|
16
|
+
if (date) {
|
|
17
|
+
this.date = date;
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
this.date = new Date();
|
|
21
|
+
}
|
|
17
22
|
}
|
|
18
23
|
year() {
|
|
19
24
|
return this.date.getFullYear().toString();
|
|
@@ -62,7 +67,7 @@ class Generateor {
|
|
|
62
67
|
}
|
|
63
68
|
class FileNameGenerator extends Generateor {
|
|
64
69
|
constructor(info) {
|
|
65
|
-
super();
|
|
70
|
+
super(info.date);
|
|
66
71
|
this.info = info;
|
|
67
72
|
}
|
|
68
73
|
fullName() {
|
|
@@ -124,13 +129,27 @@ class FileNameGenerator extends Generateor {
|
|
|
124
129
|
sha1: () => this.sha1(),
|
|
125
130
|
sha256: () => this.sha256(),
|
|
126
131
|
};
|
|
127
|
-
return Object.entries(formatters).reduce((result, [key, formatter]) =>
|
|
132
|
+
return Object.entries(formatters).reduce((result, [key, formatter]) => {
|
|
133
|
+
const simplePattern = new RegExp(`{${key}}`, 'g');
|
|
134
|
+
const truncatePattern = new RegExp(`{${key}:(\\d+)}`, 'g');
|
|
135
|
+
if (truncatePattern.test(result)) {
|
|
136
|
+
result = result.replace(truncatePattern, (match, length) => {
|
|
137
|
+
const value = formatter();
|
|
138
|
+
const truncateLength = parseInt(length, 10);
|
|
139
|
+
return value.substring(0, truncateLength);
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
else {
|
|
143
|
+
result = result.replace(simplePattern, formatter());
|
|
144
|
+
}
|
|
145
|
+
return result;
|
|
146
|
+
}, super.format(s));
|
|
128
147
|
}
|
|
129
148
|
}
|
|
130
149
|
exports.FileNameGenerator = FileNameGenerator;
|
|
131
150
|
class OutputURLGenerator extends Generateor {
|
|
132
151
|
constructor(config, info) {
|
|
133
|
-
super();
|
|
152
|
+
super(info.date);
|
|
134
153
|
this._config = config;
|
|
135
154
|
this._info = info;
|
|
136
155
|
// parse the url from storage
|
|
@@ -167,17 +186,20 @@ class OutputURLGenerator extends Generateor {
|
|
|
167
186
|
if (this._info.fileName) {
|
|
168
187
|
return this._info.fileName;
|
|
169
188
|
}
|
|
170
|
-
return path_1.default.basename(this.path());
|
|
189
|
+
return path_1.default.basename(this.path()); // will fallback to the uploaded filename.
|
|
171
190
|
}
|
|
172
191
|
extName() {
|
|
173
192
|
if (this._info.extname) {
|
|
174
193
|
return this._info.extname.replace(/^./, '');
|
|
175
194
|
}
|
|
176
|
-
return path_1.default.extname(this.path()).replace(/^./, '');
|
|
195
|
+
return path_1.default.extname(this.path()).replace(/^./, ''); // will fallback to the uploaded file extname.
|
|
177
196
|
}
|
|
178
197
|
dir() {
|
|
179
198
|
return path_1.default.dirname(this.path());
|
|
180
199
|
}
|
|
200
|
+
uploadedFileName() {
|
|
201
|
+
return path_1.default.basename(this.path());
|
|
202
|
+
}
|
|
181
203
|
originalURL() {
|
|
182
204
|
let url = this._info.url;
|
|
183
205
|
if (!url) {
|
|
@@ -218,6 +240,7 @@ class OutputURLGenerator extends Generateor {
|
|
|
218
240
|
dir: () => this.dir(),
|
|
219
241
|
fileName: () => this.fileName(),
|
|
220
242
|
path: () => this.path(),
|
|
243
|
+
uploadedFileName: () => this.uploadedFileName(),
|
|
221
244
|
extName: () => this.extName(),
|
|
222
245
|
query: () => this.query(),
|
|
223
246
|
hash: () => this.hash(),
|