@jayfong/x-utils 1.0.0-202407021055 → 1.0.0-202407021348
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/_cjs/alipan.js +173 -0
- package/_cjs/fs.js +40 -1
- package/alipan.d.ts +209 -0
- package/alipan.js +153 -0
- package/fs.d.ts +10 -1
- package/fs.js +40 -1
- package/package.json +8 -2
package/_cjs/alipan.js
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var alipan_exports = {};
|
|
20
|
+
__export(alipan_exports, {
|
|
21
|
+
XAlipan: () => XAlipan
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(alipan_exports);
|
|
24
|
+
var import_x_request = require("@jayfong/x-request");
|
|
25
|
+
var import_vtils = require("vtils");
|
|
26
|
+
var import_path = require("./path.js");
|
|
27
|
+
class XAlipan {
|
|
28
|
+
constructor(options) {
|
|
29
|
+
this.options = options;
|
|
30
|
+
this.xr = import_x_request.xr.extend({
|
|
31
|
+
baseUrl: "https://open.aliyundrive.com",
|
|
32
|
+
headers: {
|
|
33
|
+
Authorization: `Bearer ${options.accessToken}`
|
|
34
|
+
},
|
|
35
|
+
timeoutMs: (0, import_vtils.ms)("30s")
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
xr;
|
|
39
|
+
getUserInfo = (0, import_vtils.memoize)(async () => {
|
|
40
|
+
const res = await this.xr.postJson({
|
|
41
|
+
url: "/adrive/v1.0/user/getDriveInfo"
|
|
42
|
+
});
|
|
43
|
+
return res.data;
|
|
44
|
+
});
|
|
45
|
+
async createFile(payload) {
|
|
46
|
+
const res = await this.xr.postJson({
|
|
47
|
+
url: "/adrive/v1.0/openFile/create",
|
|
48
|
+
data: payload
|
|
49
|
+
});
|
|
50
|
+
return res.data;
|
|
51
|
+
}
|
|
52
|
+
async uploadFile(payload) {
|
|
53
|
+
await this.xr.post({
|
|
54
|
+
method: "PUT",
|
|
55
|
+
url: payload.useIntranet ? payload.uploadUrl.replace(
|
|
56
|
+
"https://cn-beijing-data.aliyundrive.net/",
|
|
57
|
+
"http://ccp-bj29-bj-1592982087.oss-cn-beijing-internal.aliyuncs.com/"
|
|
58
|
+
) : payload.uploadUrl,
|
|
59
|
+
data: payload.file,
|
|
60
|
+
headers: {
|
|
61
|
+
"Content-Type": ""
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
async completeFile(payload) {
|
|
66
|
+
await this.xr.post({
|
|
67
|
+
url: "/adrive/v1.0/openFile/complete",
|
|
68
|
+
data: payload
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
async getFileInfoByPath(payload) {
|
|
72
|
+
const res = await this.xr.postJson({
|
|
73
|
+
url: "/adrive/v1.0/openFile/get_by_path",
|
|
74
|
+
data: payload
|
|
75
|
+
});
|
|
76
|
+
return res.data;
|
|
77
|
+
}
|
|
78
|
+
async getFileDownloadUrl(payload) {
|
|
79
|
+
const res = await this.xr.postJson({
|
|
80
|
+
url: "/adrive/v1.0/openFile/getDownloadUrl",
|
|
81
|
+
data: payload
|
|
82
|
+
});
|
|
83
|
+
return res.data;
|
|
84
|
+
}
|
|
85
|
+
getDriveId = (0, import_vtils.memoize)(
|
|
86
|
+
async (payload) => {
|
|
87
|
+
{
|
|
88
|
+
const userInfo = await this.getUserInfo();
|
|
89
|
+
return payload.drive === "backup" ? userInfo.backup_drive_id : payload.drive === "resource" ? userInfo.resource_drive_id : payload.drive === "album" ? userInfo.album_drive_id : "";
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
(payload) => payload.drive
|
|
93
|
+
);
|
|
94
|
+
async existsFileHuman(payload) {
|
|
95
|
+
try {
|
|
96
|
+
const driveId = await this.getDriveId(payload);
|
|
97
|
+
const res = await this.getFileInfoByPath({
|
|
98
|
+
drive_id: driveId,
|
|
99
|
+
file_path: payload.path
|
|
100
|
+
});
|
|
101
|
+
return res.file_id;
|
|
102
|
+
} catch {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
ensurePathHuman = (0, import_vtils.memoize)(
|
|
107
|
+
async (payload) => {
|
|
108
|
+
const driveId = await this.getDriveId(payload);
|
|
109
|
+
const pathParts = payload.path.split("/");
|
|
110
|
+
let prevFileId = "root";
|
|
111
|
+
for (let i = 1; i < pathParts.length; i++) {
|
|
112
|
+
const path = pathParts.slice(0, i + 1).join("/");
|
|
113
|
+
const fileId = await this.existsFileHuman({
|
|
114
|
+
drive: payload.drive,
|
|
115
|
+
path
|
|
116
|
+
});
|
|
117
|
+
if (!fileId) {
|
|
118
|
+
const createRes = await this.createFile({
|
|
119
|
+
drive_id: driveId,
|
|
120
|
+
parent_file_id: prevFileId,
|
|
121
|
+
type: "folder",
|
|
122
|
+
check_name_mode: "refuse",
|
|
123
|
+
name: pathParts[i]
|
|
124
|
+
});
|
|
125
|
+
prevFileId = createRes.file_id;
|
|
126
|
+
} else {
|
|
127
|
+
prevFileId = fileId;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return prevFileId;
|
|
131
|
+
},
|
|
132
|
+
(payload) => `${payload.drive}:${payload.path}`
|
|
133
|
+
);
|
|
134
|
+
async uploadFileHuman(payload) {
|
|
135
|
+
const driveId = await this.getDriveId(payload);
|
|
136
|
+
const fileId = await this.ensurePathHuman({
|
|
137
|
+
drive: payload.drive,
|
|
138
|
+
path: import_path.XPath.dirname(payload.path)
|
|
139
|
+
});
|
|
140
|
+
const createRes = await this.createFile({
|
|
141
|
+
drive_id: driveId,
|
|
142
|
+
parent_file_id: fileId,
|
|
143
|
+
type: "file",
|
|
144
|
+
check_name_mode: "refuse",
|
|
145
|
+
name: import_path.XPath.basename(payload.path)
|
|
146
|
+
});
|
|
147
|
+
if (!createRes.exist && createRes.part_info_list?.length === 1) {
|
|
148
|
+
await this.uploadFile({
|
|
149
|
+
uploadUrl: createRes.part_info_list[0].upload_url,
|
|
150
|
+
file: payload.file,
|
|
151
|
+
useIntranet: payload.useIntranet
|
|
152
|
+
});
|
|
153
|
+
await this.completeFile({
|
|
154
|
+
drive_id: createRes.drive_id,
|
|
155
|
+
file_id: createRes.file_id,
|
|
156
|
+
upload_id: createRes.upload_id
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
async getFileDownloadUrlHuman(payload) {
|
|
161
|
+
const driveId = await this.getDriveId(payload);
|
|
162
|
+
const fileInfo = await this.getFileInfoByPath({
|
|
163
|
+
drive_id: driveId,
|
|
164
|
+
file_path: payload.path
|
|
165
|
+
});
|
|
166
|
+
const downloadInfo = await this.getFileDownloadUrl({
|
|
167
|
+
drive_id: driveId,
|
|
168
|
+
file_id: fileInfo.file_id,
|
|
169
|
+
expire_sec: 900
|
|
170
|
+
});
|
|
171
|
+
return downloadInfo.url;
|
|
172
|
+
}
|
|
173
|
+
}
|
package/_cjs/fs.js
CHANGED
|
@@ -32,4 +32,43 @@ __export(fs_exports, {
|
|
|
32
32
|
});
|
|
33
33
|
module.exports = __toCommonJS(fs_exports);
|
|
34
34
|
var import_fs_extra = __toESM(require("fs-extra"), 1);
|
|
35
|
-
|
|
35
|
+
var import_mime = __toESM(require("mime"), 1);
|
|
36
|
+
const XFsExtra = {
|
|
37
|
+
getMimeType(extOrName) {
|
|
38
|
+
return import_mime.default.getType(extOrName) || "application/octet-stream";
|
|
39
|
+
},
|
|
40
|
+
getExtension(typeOrName) {
|
|
41
|
+
if (typeOrName.includes(".")) {
|
|
42
|
+
return typeOrName.split(".").pop();
|
|
43
|
+
}
|
|
44
|
+
return import_mime.default.getExtension(typeOrName) || "";
|
|
45
|
+
},
|
|
46
|
+
async toBuffer(file) {
|
|
47
|
+
if (Buffer.isBuffer(file)) {
|
|
48
|
+
return file;
|
|
49
|
+
}
|
|
50
|
+
const chunks = [];
|
|
51
|
+
for await (const chunk of file) {
|
|
52
|
+
chunks.push(chunk);
|
|
53
|
+
}
|
|
54
|
+
const buffer = Buffer.concat(chunks);
|
|
55
|
+
return buffer;
|
|
56
|
+
},
|
|
57
|
+
async toText(file) {
|
|
58
|
+
const buffer = Buffer.isBuffer(file) ? file : await XFsExtra.toBuffer(file);
|
|
59
|
+
return buffer.toString("utf-8");
|
|
60
|
+
},
|
|
61
|
+
async toMaskImage(file) {
|
|
62
|
+
const buffers = [
|
|
63
|
+
// PNG 文件头
|
|
64
|
+
// https://zh.wikipedia.org/wiki/PNG
|
|
65
|
+
Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]),
|
|
66
|
+
await XFsExtra.toBuffer(file)
|
|
67
|
+
];
|
|
68
|
+
return Buffer.concat(buffers);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
const XFs = {
|
|
72
|
+
...import_fs_extra.default,
|
|
73
|
+
...XFsExtra
|
|
74
|
+
};
|
package/alipan.d.ts
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/// <reference types="lodash" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
type GetUserInfoResult = {
|
|
4
|
+
name: string;
|
|
5
|
+
avatar: string;
|
|
6
|
+
user_id: string;
|
|
7
|
+
user_name: string;
|
|
8
|
+
nick_name: string;
|
|
9
|
+
default_drive_id: string;
|
|
10
|
+
backup_drive_id: string;
|
|
11
|
+
resource_drive_id: string;
|
|
12
|
+
album_drive_id: string;
|
|
13
|
+
};
|
|
14
|
+
type CreateFilePayload = {
|
|
15
|
+
drive_id: string;
|
|
16
|
+
parent_file_id: string;
|
|
17
|
+
name: string;
|
|
18
|
+
type: 'file' | 'folder';
|
|
19
|
+
check_name_mode: 'auto_rename' | 'refuse' | 'ignore';
|
|
20
|
+
};
|
|
21
|
+
type CreateFileResult = {
|
|
22
|
+
trashed?: any;
|
|
23
|
+
name?: any;
|
|
24
|
+
thumbnail?: any;
|
|
25
|
+
type: string;
|
|
26
|
+
category?: any;
|
|
27
|
+
hidden?: any;
|
|
28
|
+
status?: any;
|
|
29
|
+
description?: any;
|
|
30
|
+
meta?: any;
|
|
31
|
+
url?: any;
|
|
32
|
+
size?: any;
|
|
33
|
+
starred?: any;
|
|
34
|
+
available?: any;
|
|
35
|
+
exist?: any;
|
|
36
|
+
user_tags?: any;
|
|
37
|
+
mime_type?: any;
|
|
38
|
+
parent_file_id: string;
|
|
39
|
+
drive_id: string;
|
|
40
|
+
file_id: string;
|
|
41
|
+
file_extension?: any;
|
|
42
|
+
revision_id: string;
|
|
43
|
+
content_hash?: any;
|
|
44
|
+
content_hash_name?: any;
|
|
45
|
+
encrypt_mode: string;
|
|
46
|
+
domain_id: string;
|
|
47
|
+
download_url?: any;
|
|
48
|
+
user_meta?: any;
|
|
49
|
+
content_type?: any;
|
|
50
|
+
created_at?: any;
|
|
51
|
+
updated_at?: any;
|
|
52
|
+
local_created_at?: any;
|
|
53
|
+
local_modified_at?: any;
|
|
54
|
+
trashed_at?: any;
|
|
55
|
+
punish_flag?: any;
|
|
56
|
+
file_name: string;
|
|
57
|
+
upload_id: string;
|
|
58
|
+
location: string;
|
|
59
|
+
rapid_upload: boolean;
|
|
60
|
+
part_info_list: {
|
|
61
|
+
etag?: any;
|
|
62
|
+
part_number: number;
|
|
63
|
+
part_size?: any;
|
|
64
|
+
upload_url: string;
|
|
65
|
+
content_type: string;
|
|
66
|
+
upload_form_info?: any;
|
|
67
|
+
}[];
|
|
68
|
+
streams_upload_info?: any;
|
|
69
|
+
};
|
|
70
|
+
type UploadFilePayload = {
|
|
71
|
+
uploadUrl: string;
|
|
72
|
+
file: Buffer;
|
|
73
|
+
useIntranet?: boolean;
|
|
74
|
+
};
|
|
75
|
+
type CompleteFilePayload = {
|
|
76
|
+
drive_id: string;
|
|
77
|
+
file_id: string;
|
|
78
|
+
upload_id: string;
|
|
79
|
+
};
|
|
80
|
+
type GetFileInfoByPathPayload = {
|
|
81
|
+
drive_id: string;
|
|
82
|
+
file_path: string;
|
|
83
|
+
};
|
|
84
|
+
type GetFileInfoByPathResult = {
|
|
85
|
+
trashed: boolean;
|
|
86
|
+
name: string;
|
|
87
|
+
thumbnail: string;
|
|
88
|
+
type: string;
|
|
89
|
+
category: string;
|
|
90
|
+
hidden: boolean;
|
|
91
|
+
status: string;
|
|
92
|
+
description?: any;
|
|
93
|
+
meta?: any;
|
|
94
|
+
url?: any;
|
|
95
|
+
size: number;
|
|
96
|
+
starred: boolean;
|
|
97
|
+
location?: any;
|
|
98
|
+
deleted?: any;
|
|
99
|
+
channel?: any;
|
|
100
|
+
user_tags?: any;
|
|
101
|
+
mime_type?: any;
|
|
102
|
+
parent_file_id: string;
|
|
103
|
+
drive_id: string;
|
|
104
|
+
file_id: string;
|
|
105
|
+
file_extension: string;
|
|
106
|
+
revision_id: string;
|
|
107
|
+
content_hash: string;
|
|
108
|
+
content_hash_name: string;
|
|
109
|
+
encrypt_mode: string;
|
|
110
|
+
domain_id?: any;
|
|
111
|
+
download_url?: any;
|
|
112
|
+
user_meta?: any;
|
|
113
|
+
content_type: string;
|
|
114
|
+
created_at: string;
|
|
115
|
+
updated_at: string;
|
|
116
|
+
local_created_at: string;
|
|
117
|
+
local_modified_at: string;
|
|
118
|
+
trashed_at?: any;
|
|
119
|
+
punish_flag: number;
|
|
120
|
+
video_media_metadata?: any;
|
|
121
|
+
image_media_metadata: {
|
|
122
|
+
address_line?: any;
|
|
123
|
+
city?: any;
|
|
124
|
+
country?: any;
|
|
125
|
+
district?: any;
|
|
126
|
+
faces?: any;
|
|
127
|
+
height: number;
|
|
128
|
+
image_quality: {
|
|
129
|
+
clarity?: any;
|
|
130
|
+
clarityScore?: any;
|
|
131
|
+
color?: any;
|
|
132
|
+
colorScore?: any;
|
|
133
|
+
compositionScore?: any;
|
|
134
|
+
contrast?: any;
|
|
135
|
+
contrastScore?: any;
|
|
136
|
+
exposure?: any;
|
|
137
|
+
exposureScore?: any;
|
|
138
|
+
overallScore: {
|
|
139
|
+
s: number;
|
|
140
|
+
e: number;
|
|
141
|
+
c: number[];
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
location?: any;
|
|
145
|
+
province?: any;
|
|
146
|
+
story_image_score?: any;
|
|
147
|
+
time?: any;
|
|
148
|
+
township?: any;
|
|
149
|
+
width: number;
|
|
150
|
+
exif?: any;
|
|
151
|
+
};
|
|
152
|
+
};
|
|
153
|
+
type GetFileDownloadUrlPayload = {
|
|
154
|
+
drive_id: string;
|
|
155
|
+
file_id: string;
|
|
156
|
+
expire_sec?: number;
|
|
157
|
+
};
|
|
158
|
+
type GetFileDownloadUrlResult = {
|
|
159
|
+
method: string;
|
|
160
|
+
url: string;
|
|
161
|
+
expiration: string;
|
|
162
|
+
size: number;
|
|
163
|
+
streamsUrl?: any;
|
|
164
|
+
content_hash: string;
|
|
165
|
+
content_hash_name: string;
|
|
166
|
+
file_id: string;
|
|
167
|
+
};
|
|
168
|
+
type DriveType = 'backup' | 'resource' | 'album';
|
|
169
|
+
type GetDriveIdPayload = {
|
|
170
|
+
drive: DriveType;
|
|
171
|
+
};
|
|
172
|
+
type ExistsFileHumanPayload = {
|
|
173
|
+
drive: DriveType;
|
|
174
|
+
path: string;
|
|
175
|
+
};
|
|
176
|
+
type EnsurePathHumanPayload = {
|
|
177
|
+
drive: DriveType;
|
|
178
|
+
path: string;
|
|
179
|
+
};
|
|
180
|
+
type UploadFileHumanPayload = {
|
|
181
|
+
drive: DriveType;
|
|
182
|
+
path: string;
|
|
183
|
+
file: Buffer;
|
|
184
|
+
useIntranet?: boolean;
|
|
185
|
+
};
|
|
186
|
+
type GetFileDownloadUrlHumanPayload = {
|
|
187
|
+
drive: DriveType;
|
|
188
|
+
path: string;
|
|
189
|
+
};
|
|
190
|
+
export type XAlipanOptions = {
|
|
191
|
+
accessToken: string;
|
|
192
|
+
};
|
|
193
|
+
export declare class XAlipan {
|
|
194
|
+
private options;
|
|
195
|
+
private xr;
|
|
196
|
+
constructor(options: XAlipanOptions);
|
|
197
|
+
getUserInfo: (() => Promise<GetUserInfoResult>) & import("lodash").MemoizedFunction;
|
|
198
|
+
createFile(payload: CreateFilePayload): Promise<CreateFileResult>;
|
|
199
|
+
uploadFile(payload: UploadFilePayload): Promise<void>;
|
|
200
|
+
completeFile(payload: CompleteFilePayload): Promise<void>;
|
|
201
|
+
getFileInfoByPath(payload: GetFileInfoByPathPayload): Promise<GetFileInfoByPathResult>;
|
|
202
|
+
getFileDownloadUrl(payload: GetFileDownloadUrlPayload): Promise<GetFileDownloadUrlResult>;
|
|
203
|
+
getDriveId: ((payload: GetDriveIdPayload) => Promise<string>) & import("lodash").MemoizedFunction;
|
|
204
|
+
existsFileHuman(payload: ExistsFileHumanPayload): Promise<string | false>;
|
|
205
|
+
ensurePathHuman: ((payload: EnsurePathHumanPayload) => Promise<string>) & import("lodash").MemoizedFunction;
|
|
206
|
+
uploadFileHuman(payload: UploadFileHumanPayload): Promise<void>;
|
|
207
|
+
getFileDownloadUrlHuman(payload: GetFileDownloadUrlHumanPayload): Promise<string>;
|
|
208
|
+
}
|
|
209
|
+
export {};
|
package/alipan.js
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { xr } from "@jayfong/x-request";
|
|
2
|
+
import { memoize, ms } from "vtils";
|
|
3
|
+
import { XPath } from "./path.js";
|
|
4
|
+
class XAlipan {
|
|
5
|
+
constructor(options) {
|
|
6
|
+
this.options = options;
|
|
7
|
+
this.xr = xr.extend({
|
|
8
|
+
baseUrl: "https://open.aliyundrive.com",
|
|
9
|
+
headers: {
|
|
10
|
+
Authorization: `Bearer ${options.accessToken}`
|
|
11
|
+
},
|
|
12
|
+
timeoutMs: ms("30s")
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
xr;
|
|
16
|
+
getUserInfo = memoize(async () => {
|
|
17
|
+
const res = await this.xr.postJson({
|
|
18
|
+
url: "/adrive/v1.0/user/getDriveInfo"
|
|
19
|
+
});
|
|
20
|
+
return res.data;
|
|
21
|
+
});
|
|
22
|
+
async createFile(payload) {
|
|
23
|
+
const res = await this.xr.postJson({
|
|
24
|
+
url: "/adrive/v1.0/openFile/create",
|
|
25
|
+
data: payload
|
|
26
|
+
});
|
|
27
|
+
return res.data;
|
|
28
|
+
}
|
|
29
|
+
async uploadFile(payload) {
|
|
30
|
+
await this.xr.post({
|
|
31
|
+
method: "PUT",
|
|
32
|
+
url: payload.useIntranet ? payload.uploadUrl.replace(
|
|
33
|
+
"https://cn-beijing-data.aliyundrive.net/",
|
|
34
|
+
"http://ccp-bj29-bj-1592982087.oss-cn-beijing-internal.aliyuncs.com/"
|
|
35
|
+
) : payload.uploadUrl,
|
|
36
|
+
data: payload.file,
|
|
37
|
+
headers: {
|
|
38
|
+
"Content-Type": ""
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
async completeFile(payload) {
|
|
43
|
+
await this.xr.post({
|
|
44
|
+
url: "/adrive/v1.0/openFile/complete",
|
|
45
|
+
data: payload
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
async getFileInfoByPath(payload) {
|
|
49
|
+
const res = await this.xr.postJson({
|
|
50
|
+
url: "/adrive/v1.0/openFile/get_by_path",
|
|
51
|
+
data: payload
|
|
52
|
+
});
|
|
53
|
+
return res.data;
|
|
54
|
+
}
|
|
55
|
+
async getFileDownloadUrl(payload) {
|
|
56
|
+
const res = await this.xr.postJson({
|
|
57
|
+
url: "/adrive/v1.0/openFile/getDownloadUrl",
|
|
58
|
+
data: payload
|
|
59
|
+
});
|
|
60
|
+
return res.data;
|
|
61
|
+
}
|
|
62
|
+
getDriveId = memoize(
|
|
63
|
+
async (payload) => {
|
|
64
|
+
{
|
|
65
|
+
const userInfo = await this.getUserInfo();
|
|
66
|
+
return payload.drive === "backup" ? userInfo.backup_drive_id : payload.drive === "resource" ? userInfo.resource_drive_id : payload.drive === "album" ? userInfo.album_drive_id : "";
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
(payload) => payload.drive
|
|
70
|
+
);
|
|
71
|
+
async existsFileHuman(payload) {
|
|
72
|
+
try {
|
|
73
|
+
const driveId = await this.getDriveId(payload);
|
|
74
|
+
const res = await this.getFileInfoByPath({
|
|
75
|
+
drive_id: driveId,
|
|
76
|
+
file_path: payload.path
|
|
77
|
+
});
|
|
78
|
+
return res.file_id;
|
|
79
|
+
} catch {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
ensurePathHuman = memoize(
|
|
84
|
+
async (payload) => {
|
|
85
|
+
const driveId = await this.getDriveId(payload);
|
|
86
|
+
const pathParts = payload.path.split("/");
|
|
87
|
+
let prevFileId = "root";
|
|
88
|
+
for (let i = 1; i < pathParts.length; i++) {
|
|
89
|
+
const path = pathParts.slice(0, i + 1).join("/");
|
|
90
|
+
const fileId = await this.existsFileHuman({
|
|
91
|
+
drive: payload.drive,
|
|
92
|
+
path
|
|
93
|
+
});
|
|
94
|
+
if (!fileId) {
|
|
95
|
+
const createRes = await this.createFile({
|
|
96
|
+
drive_id: driveId,
|
|
97
|
+
parent_file_id: prevFileId,
|
|
98
|
+
type: "folder",
|
|
99
|
+
check_name_mode: "refuse",
|
|
100
|
+
name: pathParts[i]
|
|
101
|
+
});
|
|
102
|
+
prevFileId = createRes.file_id;
|
|
103
|
+
} else {
|
|
104
|
+
prevFileId = fileId;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return prevFileId;
|
|
108
|
+
},
|
|
109
|
+
(payload) => `${payload.drive}:${payload.path}`
|
|
110
|
+
);
|
|
111
|
+
async uploadFileHuman(payload) {
|
|
112
|
+
const driveId = await this.getDriveId(payload);
|
|
113
|
+
const fileId = await this.ensurePathHuman({
|
|
114
|
+
drive: payload.drive,
|
|
115
|
+
path: XPath.dirname(payload.path)
|
|
116
|
+
});
|
|
117
|
+
const createRes = await this.createFile({
|
|
118
|
+
drive_id: driveId,
|
|
119
|
+
parent_file_id: fileId,
|
|
120
|
+
type: "file",
|
|
121
|
+
check_name_mode: "refuse",
|
|
122
|
+
name: XPath.basename(payload.path)
|
|
123
|
+
});
|
|
124
|
+
if (!createRes.exist && createRes.part_info_list?.length === 1) {
|
|
125
|
+
await this.uploadFile({
|
|
126
|
+
uploadUrl: createRes.part_info_list[0].upload_url,
|
|
127
|
+
file: payload.file,
|
|
128
|
+
useIntranet: payload.useIntranet
|
|
129
|
+
});
|
|
130
|
+
await this.completeFile({
|
|
131
|
+
drive_id: createRes.drive_id,
|
|
132
|
+
file_id: createRes.file_id,
|
|
133
|
+
upload_id: createRes.upload_id
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
async getFileDownloadUrlHuman(payload) {
|
|
138
|
+
const driveId = await this.getDriveId(payload);
|
|
139
|
+
const fileInfo = await this.getFileInfoByPath({
|
|
140
|
+
drive_id: driveId,
|
|
141
|
+
file_path: payload.path
|
|
142
|
+
});
|
|
143
|
+
const downloadInfo = await this.getFileDownloadUrl({
|
|
144
|
+
drive_id: driveId,
|
|
145
|
+
file_id: fileInfo.file_id,
|
|
146
|
+
expire_sec: 900
|
|
147
|
+
});
|
|
148
|
+
return downloadInfo.url;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
export {
|
|
152
|
+
XAlipan
|
|
153
|
+
};
|
package/fs.d.ts
CHANGED
|
@@ -1,2 +1,11 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
1
3
|
import fs from 'fs-extra';
|
|
2
|
-
|
|
4
|
+
import { Readable } from 'node:stream';
|
|
5
|
+
export declare const XFs: typeof fs & {
|
|
6
|
+
getMimeType(extOrName: string): string;
|
|
7
|
+
getExtension(typeOrName: string): string;
|
|
8
|
+
toBuffer(file: Buffer | Readable): Promise<Buffer>;
|
|
9
|
+
toText(file: Buffer | Readable): Promise<string>;
|
|
10
|
+
toMaskImage(file: Buffer | Readable): Promise<Buffer>;
|
|
11
|
+
};
|
package/fs.js
CHANGED
|
@@ -1,5 +1,44 @@
|
|
|
1
1
|
import fs from "fs-extra";
|
|
2
|
-
|
|
2
|
+
import mime from "mime";
|
|
3
|
+
const XFsExtra = {
|
|
4
|
+
getMimeType(extOrName) {
|
|
5
|
+
return mime.getType(extOrName) || "application/octet-stream";
|
|
6
|
+
},
|
|
7
|
+
getExtension(typeOrName) {
|
|
8
|
+
if (typeOrName.includes(".")) {
|
|
9
|
+
return typeOrName.split(".").pop();
|
|
10
|
+
}
|
|
11
|
+
return mime.getExtension(typeOrName) || "";
|
|
12
|
+
},
|
|
13
|
+
async toBuffer(file) {
|
|
14
|
+
if (Buffer.isBuffer(file)) {
|
|
15
|
+
return file;
|
|
16
|
+
}
|
|
17
|
+
const chunks = [];
|
|
18
|
+
for await (const chunk of file) {
|
|
19
|
+
chunks.push(chunk);
|
|
20
|
+
}
|
|
21
|
+
const buffer = Buffer.concat(chunks);
|
|
22
|
+
return buffer;
|
|
23
|
+
},
|
|
24
|
+
async toText(file) {
|
|
25
|
+
const buffer = Buffer.isBuffer(file) ? file : await XFsExtra.toBuffer(file);
|
|
26
|
+
return buffer.toString("utf-8");
|
|
27
|
+
},
|
|
28
|
+
async toMaskImage(file) {
|
|
29
|
+
const buffers = [
|
|
30
|
+
// PNG 文件头
|
|
31
|
+
// https://zh.wikipedia.org/wiki/PNG
|
|
32
|
+
Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]),
|
|
33
|
+
await XFsExtra.toBuffer(file)
|
|
34
|
+
];
|
|
35
|
+
return Buffer.concat(buffers);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
const XFs = {
|
|
39
|
+
...fs,
|
|
40
|
+
...XFsExtra
|
|
41
|
+
};
|
|
3
42
|
export {
|
|
4
43
|
XFs
|
|
5
44
|
};
|
package/package.json
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jayfong/x-utils",
|
|
3
3
|
"description": "123456",
|
|
4
|
-
"version": "1.0.0-
|
|
4
|
+
"version": "1.0.0-202407021348",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"dependencies": {
|
|
7
7
|
"vtils": "^4.115.0",
|
|
8
|
+
"@jayfong/x-request": "^2.35.2",
|
|
8
9
|
"cli-table3": "^0.6.3",
|
|
9
10
|
"inquirer": "^9.2.13",
|
|
10
11
|
"clipboardy": "^4.0.0",
|
|
11
12
|
"execa": "^8.0.1",
|
|
12
|
-
"@jayfong/x-request": "^2.35.2",
|
|
13
13
|
"node-html-parser": "^6.1.12",
|
|
14
14
|
"csv": "^6.3.6",
|
|
15
15
|
"exit-hook": "^4.0.0",
|
|
16
16
|
"fs-extra": "^11.2.0",
|
|
17
17
|
"dotenv": "^16.4.5",
|
|
18
|
+
"mime": "^4.0.3",
|
|
18
19
|
"docx": "^8.5.0",
|
|
19
20
|
"image-dimensions": "^2.3.0",
|
|
20
21
|
"@fastify/cors": "^9.0.1",
|
|
@@ -38,6 +39,11 @@
|
|
|
38
39
|
"import": "./ai.js",
|
|
39
40
|
"types": "./ai.d.ts"
|
|
40
41
|
},
|
|
42
|
+
"./alipan": {
|
|
43
|
+
"require": "./_cjs/alipan.js",
|
|
44
|
+
"import": "./alipan.js",
|
|
45
|
+
"types": "./alipan.d.ts"
|
|
46
|
+
},
|
|
41
47
|
"./cli": {
|
|
42
48
|
"require": "./_cjs/cli.js",
|
|
43
49
|
"import": "./cli.js",
|