@nekosuneprojects/nekosunevrtools 1.1.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/.github/workflows/ci.yml +33 -0
- package/.github/workflows/npm-publish-github-packages.yml +35 -0
- package/.github/workflows/npm-publish.yml +34 -0
- package/README.md +201 -0
- package/bin/nekosunevrtools.js +13 -0
- package/package.json +31 -0
- package/src/cli.js +550 -0
- package/src/earnings.js +128 -0
- package/src/index.d.ts +174 -0
- package/src/index.js +25 -0
- package/src/shorturl/provider/adlinkfly-compatible.js +73 -0
- package/src/shorturl/provider/presets.js +37 -0
- package/src/shorturl/providers.js +11 -0
- package/src/upload/client.js +57 -0
- package/src/upload/provider/catbox.js +68 -0
- package/src/upload/provider/fileio.js +64 -0
- package/src/upload/provider/transfersh.js +58 -0
- package/src/upload/provider/upfiles.js +67 -0
- package/src/upload/providers.js +11 -0
- package/src/upload-client.js +1 -0
- package/src/utils/file.js +66 -0
- package/src/video/provider/doodstream.js +228 -0
- package/src/video/providers.js +5 -0
package/src/index.d.ts
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
export interface UploadResult {
|
|
2
|
+
platform: string;
|
|
3
|
+
success: boolean;
|
|
4
|
+
url: string;
|
|
5
|
+
raw: unknown;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export type UploadPhase = "start" | "uploading" | "complete" | "error";
|
|
9
|
+
|
|
10
|
+
export interface UploadProgress {
|
|
11
|
+
phase: UploadPhase;
|
|
12
|
+
filename: string;
|
|
13
|
+
totalBytes: number;
|
|
14
|
+
bytesTransferred: number;
|
|
15
|
+
percent: number;
|
|
16
|
+
message?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface UploadContext {
|
|
20
|
+
filePath: string;
|
|
21
|
+
apiKey?: string | null;
|
|
22
|
+
metadata?: Record<string, string>;
|
|
23
|
+
headers?: Record<string, string>;
|
|
24
|
+
onProgress?: ((progress: UploadProgress) => void) | null;
|
|
25
|
+
http: unknown;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface UploadAdapter {
|
|
29
|
+
upload(context: UploadContext): Promise<UploadResult>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface UploadOptions {
|
|
33
|
+
platform?: string;
|
|
34
|
+
apiKey?: string;
|
|
35
|
+
metadata?: Record<string, string>;
|
|
36
|
+
headers?: Record<string, string>;
|
|
37
|
+
timeoutMs?: number;
|
|
38
|
+
onProgress?: (progress: UploadProgress) => void;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface UploadClientOptions {
|
|
42
|
+
platform?: string;
|
|
43
|
+
apiKey?: string;
|
|
44
|
+
timeoutMs?: number;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export declare class UploadClient {
|
|
48
|
+
constructor(options?: UploadClientOptions);
|
|
49
|
+
registerPlatform(name: string, adapter: UploadAdapter): this;
|
|
50
|
+
upload(filePath: string, options?: UploadOptions): Promise<UploadResult>;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface ShortenResult {
|
|
54
|
+
provider: string;
|
|
55
|
+
success: boolean;
|
|
56
|
+
shortUrl: string;
|
|
57
|
+
raw: unknown;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface VideoUploadResult {
|
|
61
|
+
provider: string;
|
|
62
|
+
success: boolean;
|
|
63
|
+
videoId: string | null;
|
|
64
|
+
watchUrl: string;
|
|
65
|
+
raw: unknown;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface ShorturlAdapter {
|
|
69
|
+
shorten(context: unknown): Promise<ShortenResult>;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface VideoProviderAdapter {
|
|
73
|
+
upload(context: unknown): Promise<VideoUploadResult>;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface DoodstreamProvider extends VideoProviderAdapter {
|
|
77
|
+
cloneFile(context: unknown): Promise<{ provider: "doodstream"; success: boolean; result: unknown; raw: unknown }>;
|
|
78
|
+
remoteUploadAdd(context: unknown): Promise<{ provider: "doodstream"; success: boolean; filecode: string | null; raw: unknown }>;
|
|
79
|
+
remoteUploadList(context: unknown): Promise<{ provider: "doodstream"; success: boolean; items: unknown[]; raw: unknown }>;
|
|
80
|
+
remoteUploadStatus(context: unknown): Promise<{ provider: "doodstream"; success: boolean; items: unknown[]; raw: unknown }>;
|
|
81
|
+
remoteUploadSlots(context: unknown): Promise<{
|
|
82
|
+
provider: "doodstream";
|
|
83
|
+
success: boolean;
|
|
84
|
+
totalSlots: string | null;
|
|
85
|
+
usedSlots: string | null;
|
|
86
|
+
raw: unknown;
|
|
87
|
+
}>;
|
|
88
|
+
remoteUploadActions(context: unknown): Promise<{ provider: "doodstream"; success: boolean; raw: unknown }>;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export interface UploadAndShortenResult {
|
|
92
|
+
success: true;
|
|
93
|
+
upload: UploadResult;
|
|
94
|
+
shortlink: ShortenResult;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export interface ShortenOptions {
|
|
98
|
+
provider?: string;
|
|
99
|
+
apiKey?: string;
|
|
100
|
+
preset?: string;
|
|
101
|
+
baseUrl?: string;
|
|
102
|
+
alias?: string;
|
|
103
|
+
adsType?: number;
|
|
104
|
+
responseFormat?: "json" | "text";
|
|
105
|
+
timeoutMs?: number;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export interface UploadAndShortenOptions {
|
|
109
|
+
uploadPlatform?: string;
|
|
110
|
+
uploadApiKey?: string;
|
|
111
|
+
uploadMetadata?: Record<string, string>;
|
|
112
|
+
uploadHeaders?: Record<string, string>;
|
|
113
|
+
shortenerProvider?: string;
|
|
114
|
+
shortenerApiKey?: string;
|
|
115
|
+
shortenerPreset?: string;
|
|
116
|
+
shortenerBaseUrl?: string;
|
|
117
|
+
alias?: string;
|
|
118
|
+
adsType?: number;
|
|
119
|
+
responseFormat?: "json" | "text";
|
|
120
|
+
timeoutMs?: number;
|
|
121
|
+
onProgress?: (progress: UploadProgress) => void;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export interface VideoUploadOptions {
|
|
125
|
+
provider?: string;
|
|
126
|
+
apiKey?: string;
|
|
127
|
+
metadata?: Record<string, string>;
|
|
128
|
+
timeoutMs?: number;
|
|
129
|
+
onProgress?: (progress: UploadProgress) => void;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export declare class EarningsClient {
|
|
133
|
+
constructor(options?: {
|
|
134
|
+
timeoutMs?: number;
|
|
135
|
+
upload?: UploadClientOptions;
|
|
136
|
+
uploadClient?: UploadClient;
|
|
137
|
+
});
|
|
138
|
+
registerShortener(name: string, adapter: { shorten(context: unknown): Promise<ShortenResult> }): this;
|
|
139
|
+
registerVideoProvider(name: string, adapter: { upload(context: unknown): Promise<VideoUploadResult> }): this;
|
|
140
|
+
shortenUrl(longUrl: string, options?: ShortenOptions): Promise<ShortenResult>;
|
|
141
|
+
uploadAndShorten(filePath: string, options?: UploadAndShortenOptions): Promise<UploadAndShortenResult>;
|
|
142
|
+
uploadVideo(filePath: string, options?: VideoUploadOptions): Promise<VideoUploadResult>;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export declare const platforms: {
|
|
146
|
+
upfiles: UploadAdapter;
|
|
147
|
+
fileio: UploadAdapter;
|
|
148
|
+
catbox: UploadAdapter;
|
|
149
|
+
transfersh: UploadAdapter;
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
export declare const shortenerPresets: Record<string, string>;
|
|
153
|
+
|
|
154
|
+
export declare const upload: {
|
|
155
|
+
Client: typeof UploadClient;
|
|
156
|
+
providers: typeof platforms;
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
export declare const shorturl: {
|
|
160
|
+
providers: {
|
|
161
|
+
"adlinkfly-compatible": ShorturlAdapter;
|
|
162
|
+
};
|
|
163
|
+
presets: typeof shortenerPresets;
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
export declare const video: {
|
|
167
|
+
providers: {
|
|
168
|
+
doodstream: DoodstreamProvider;
|
|
169
|
+
};
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
export declare const earnings: {
|
|
173
|
+
Client: typeof EarningsClient;
|
|
174
|
+
};
|
package/src/index.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const { UploadClient, providers: uploadProviders } = require("./upload/client");
|
|
2
|
+
const { EarningsClient, shortenerPresets } = require("./earnings");
|
|
3
|
+
const { providers: shorturlProviders } = require("./shorturl/providers");
|
|
4
|
+
const videoProviders = require("./video/providers");
|
|
5
|
+
|
|
6
|
+
module.exports = {
|
|
7
|
+
upload: {
|
|
8
|
+
Client: UploadClient,
|
|
9
|
+
providers: uploadProviders
|
|
10
|
+
},
|
|
11
|
+
shorturl: {
|
|
12
|
+
providers: shorturlProviders,
|
|
13
|
+
presets: shortenerPresets
|
|
14
|
+
},
|
|
15
|
+
video: {
|
|
16
|
+
providers: videoProviders
|
|
17
|
+
},
|
|
18
|
+
earnings: {
|
|
19
|
+
Client: EarningsClient
|
|
20
|
+
},
|
|
21
|
+
UploadClient,
|
|
22
|
+
platforms: uploadProviders,
|
|
23
|
+
EarningsClient,
|
|
24
|
+
shortenerPresets
|
|
25
|
+
};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
async function shorten(context) {
|
|
2
|
+
const { longUrl, apiKey, http, options } = context;
|
|
3
|
+
const baseUrl = options && options.baseUrl;
|
|
4
|
+
if (!baseUrl) {
|
|
5
|
+
throw new Error('Missing shortlink baseUrl for "adlinkfly-compatible" provider.');
|
|
6
|
+
}
|
|
7
|
+
if (!apiKey) {
|
|
8
|
+
throw new Error('Missing shortlink apiKey for "adlinkfly-compatible" provider.');
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const params = {
|
|
12
|
+
api: apiKey,
|
|
13
|
+
url: longUrl
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
if (options.alias) {
|
|
17
|
+
params.alias = options.alias;
|
|
18
|
+
}
|
|
19
|
+
if (typeof options.adsType === "number") {
|
|
20
|
+
params.type = options.adsType;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const wantsText = options.responseFormat === "text";
|
|
24
|
+
if (!wantsText) {
|
|
25
|
+
params.format = "json";
|
|
26
|
+
} else {
|
|
27
|
+
params.format = "text";
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const response = await http.get(baseUrl, { params });
|
|
31
|
+
const body = response.data;
|
|
32
|
+
|
|
33
|
+
if (wantsText) {
|
|
34
|
+
const shortUrl = String(body || "").trim();
|
|
35
|
+
if (!shortUrl || !/^https?:\/\//i.test(shortUrl)) {
|
|
36
|
+
throw new Error(shortUrl || "Shortlink provider returned invalid text response.");
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
provider: options.provider || "adlinkfly-compatible",
|
|
40
|
+
success: true,
|
|
41
|
+
shortUrl,
|
|
42
|
+
raw: body
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (!body || body.status === "error") {
|
|
47
|
+
const message = normalizeErrorMessage(body && body.message);
|
|
48
|
+
throw new Error(message || "Shortlink provider returned an error.");
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const shortUrl = body.shortenedUrl || body.shortened_url || body.shortened || body.url;
|
|
52
|
+
if (!shortUrl || !/^https?:\/\//i.test(String(shortUrl))) {
|
|
53
|
+
throw new Error("Shortlink provider did not return a valid short URL.");
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return {
|
|
57
|
+
provider: options.provider || "adlinkfly-compatible",
|
|
58
|
+
success: true,
|
|
59
|
+
shortUrl: String(shortUrl),
|
|
60
|
+
raw: body
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function normalizeErrorMessage(message) {
|
|
65
|
+
if (Array.isArray(message)) {
|
|
66
|
+
return message.join(", ");
|
|
67
|
+
}
|
|
68
|
+
return message ? String(message) : "";
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
module.exports = {
|
|
72
|
+
shorten
|
|
73
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const ADLINKFLY_BASE_URLS = {
|
|
2
|
+
adlinkflyDemo: "https://demo.adlinkfly.in/api",
|
|
3
|
+
shrtfly: "https://shrtfly.com/api",
|
|
4
|
+
exei: "https://exe.io/api",
|
|
5
|
+
shrinkme: "https://shrinkme.io/api",
|
|
6
|
+
shrinkearn: "https://shrinkearn.com/api",
|
|
7
|
+
clksh: "https://clk.sh/api",
|
|
8
|
+
lnkc: "https://lnk.cu/api",
|
|
9
|
+
zinkme: "https://zinkme.com/api",
|
|
10
|
+
short2url: "https://short2url.in/api",
|
|
11
|
+
urlnama: "https://url.namaidani.net/api",
|
|
12
|
+
adshorti: "https://adshorti.xyz/api",
|
|
13
|
+
shrtbr: "https://shrtbr.com/api",
|
|
14
|
+
linkmonetizado: "https://linkmonetizado.com/api",
|
|
15
|
+
clicksfly: "https://clicksfly.com/api",
|
|
16
|
+
urlsfly: "https://urlsfly.com/api",
|
|
17
|
+
wefly: "https://wefly.me/api",
|
|
18
|
+
adbull: "https://adbull.me/api",
|
|
19
|
+
linksly: "https://linksly.co/api",
|
|
20
|
+
droplink: "https://droplink.co/api",
|
|
21
|
+
adbitfly: "https://adbitfly.com/api",
|
|
22
|
+
earnlink: "https://earnlink.io/api",
|
|
23
|
+
easycut: "https://easycut.io/api",
|
|
24
|
+
megaurl: "https://megaurl.in/api",
|
|
25
|
+
shortzon: "https://shortzon.com/api",
|
|
26
|
+
shortiio: "https://shorti.io/api",
|
|
27
|
+
adlinkcash: "https://adlinkcash.com/api",
|
|
28
|
+
adlinkic: "https://adlinkic.com/api",
|
|
29
|
+
shorte: "https://shorte.st/api",
|
|
30
|
+
link1s: "https://link1s.com/st/api",
|
|
31
|
+
cutpay: "https://cutpay.xyz/api",
|
|
32
|
+
adz7short: "https://adz7short.space/api"
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
module.exports = {
|
|
36
|
+
ADLINKFLY_BASE_URLS
|
|
37
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const adlinkflyCompatible = require("./provider/adlinkfly-compatible");
|
|
2
|
+
const { ADLINKFLY_BASE_URLS } = require("./provider/presets");
|
|
3
|
+
|
|
4
|
+
const providers = {
|
|
5
|
+
"adlinkfly-compatible": adlinkflyCompatible
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
module.exports = {
|
|
9
|
+
providers,
|
|
10
|
+
presets: ADLINKFLY_BASE_URLS
|
|
11
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
const axios = require("axios");
|
|
2
|
+
const providers = require("./providers");
|
|
3
|
+
|
|
4
|
+
class UploadClient {
|
|
5
|
+
constructor(options = {}) {
|
|
6
|
+
this.defaultPlatform = options.platform || "upfiles";
|
|
7
|
+
this.defaultApiKey = options.apiKey || null;
|
|
8
|
+
this.timeoutMs = options.timeoutMs || 60000;
|
|
9
|
+
this.adapters = { ...providers };
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
registerPlatform(name, adapter) {
|
|
13
|
+
if (!name || typeof name !== "string") {
|
|
14
|
+
throw new Error("Platform name must be a non-empty string.");
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (!adapter || typeof adapter.upload !== "function") {
|
|
18
|
+
throw new Error("Adapter must provide an upload(context) function.");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
this.adapters[name] = adapter;
|
|
22
|
+
return this;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async upload(filePath, options = {}) {
|
|
26
|
+
if (!filePath || typeof filePath !== "string") {
|
|
27
|
+
throw new Error("filePath is required and must be a string.");
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const platform = options.platform || this.defaultPlatform;
|
|
31
|
+
const adapter = this.adapters[platform];
|
|
32
|
+
if (!adapter) {
|
|
33
|
+
throw new Error(
|
|
34
|
+
`Unsupported platform "${platform}". Registered: ${Object.keys(this.adapters).join(", ")}`
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const apiKey = options.apiKey || this.defaultApiKey || null;
|
|
39
|
+
const timeoutMs = options.timeoutMs || this.timeoutMs;
|
|
40
|
+
const headers = options.headers || {};
|
|
41
|
+
const onProgress = typeof options.onProgress === "function" ? options.onProgress : null;
|
|
42
|
+
|
|
43
|
+
return adapter.upload({
|
|
44
|
+
filePath,
|
|
45
|
+
apiKey,
|
|
46
|
+
metadata: options.metadata || {},
|
|
47
|
+
headers,
|
|
48
|
+
http: axios.create({ timeout: timeoutMs }),
|
|
49
|
+
onProgress
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
module.exports = {
|
|
55
|
+
UploadClient,
|
|
56
|
+
providers
|
|
57
|
+
};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
const FormData = require("form-data");
|
|
2
|
+
const { createProgressFilePart } = require("../../utils/file");
|
|
3
|
+
|
|
4
|
+
async function upload(context) {
|
|
5
|
+
const { filePath, apiKey, metadata, headers, http, onProgress } = context;
|
|
6
|
+
|
|
7
|
+
const form = new FormData();
|
|
8
|
+
const filePart = createProgressFilePart(filePath, onProgress);
|
|
9
|
+
form.append("reqtype", "fileupload");
|
|
10
|
+
if (apiKey) {
|
|
11
|
+
form.append("userhash", apiKey);
|
|
12
|
+
}
|
|
13
|
+
form.append("fileToUpload", filePart.stream, filePart.filename);
|
|
14
|
+
|
|
15
|
+
for (const [key, value] of Object.entries(metadata || {})) {
|
|
16
|
+
form.append(key, value);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
let response;
|
|
20
|
+
try {
|
|
21
|
+
response = await http.post("https://catbox.moe/user/api.php", form, {
|
|
22
|
+
headers: {
|
|
23
|
+
...form.getHeaders(),
|
|
24
|
+
...headers
|
|
25
|
+
},
|
|
26
|
+
maxBodyLength: Infinity,
|
|
27
|
+
responseType: "text",
|
|
28
|
+
transformResponse: [(data) => data]
|
|
29
|
+
});
|
|
30
|
+
} catch (error) {
|
|
31
|
+
if (typeof onProgress === "function") {
|
|
32
|
+
onProgress({
|
|
33
|
+
phase: "error",
|
|
34
|
+
filename: filePart.filename,
|
|
35
|
+
totalBytes: filePart.totalBytes,
|
|
36
|
+
bytesTransferred: 0,
|
|
37
|
+
percent: 0,
|
|
38
|
+
message: error.message
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
throw error;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const raw = String(response.data || "").trim();
|
|
45
|
+
if (!raw || /^error/i.test(raw)) {
|
|
46
|
+
throw new Error(raw || "Catbox upload failed.");
|
|
47
|
+
}
|
|
48
|
+
if (typeof onProgress === "function") {
|
|
49
|
+
onProgress({
|
|
50
|
+
phase: "complete",
|
|
51
|
+
filename: filePart.filename,
|
|
52
|
+
totalBytes: filePart.totalBytes,
|
|
53
|
+
bytesTransferred: filePart.totalBytes,
|
|
54
|
+
percent: 100
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return {
|
|
59
|
+
platform: "catbox",
|
|
60
|
+
success: true,
|
|
61
|
+
url: raw,
|
|
62
|
+
raw
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
module.exports = {
|
|
67
|
+
upload
|
|
68
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
const FormData = require("form-data");
|
|
2
|
+
const { createProgressFilePart } = require("../../utils/file");
|
|
3
|
+
|
|
4
|
+
async function upload(context) {
|
|
5
|
+
const { filePath, metadata, headers, http, onProgress } = context;
|
|
6
|
+
|
|
7
|
+
const form = new FormData();
|
|
8
|
+
const filePart = createProgressFilePart(filePath, onProgress);
|
|
9
|
+
form.append("file", filePart.stream, filePart.filename);
|
|
10
|
+
|
|
11
|
+
if (metadata.expires) {
|
|
12
|
+
form.append("expires", metadata.expires);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
let response;
|
|
16
|
+
try {
|
|
17
|
+
response = await http.post("https://file.io", form, {
|
|
18
|
+
headers: {
|
|
19
|
+
...form.getHeaders(),
|
|
20
|
+
...headers
|
|
21
|
+
},
|
|
22
|
+
maxBodyLength: Infinity
|
|
23
|
+
});
|
|
24
|
+
} catch (error) {
|
|
25
|
+
if (typeof onProgress === "function") {
|
|
26
|
+
onProgress({
|
|
27
|
+
phase: "error",
|
|
28
|
+
filename: filePart.filename,
|
|
29
|
+
totalBytes: filePart.totalBytes,
|
|
30
|
+
bytesTransferred: 0,
|
|
31
|
+
percent: 0,
|
|
32
|
+
message: error.message
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
throw error;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const body = response.data || {};
|
|
39
|
+
const link = body.link || body.url;
|
|
40
|
+
const success = Boolean(body.success && link);
|
|
41
|
+
if (!success) {
|
|
42
|
+
throw new Error(body.message || "file.io upload failed.");
|
|
43
|
+
}
|
|
44
|
+
if (typeof onProgress === "function") {
|
|
45
|
+
onProgress({
|
|
46
|
+
phase: "complete",
|
|
47
|
+
filename: filePart.filename,
|
|
48
|
+
totalBytes: filePart.totalBytes,
|
|
49
|
+
bytesTransferred: filePart.totalBytes,
|
|
50
|
+
percent: 100
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
platform: "fileio",
|
|
56
|
+
success: true,
|
|
57
|
+
url: link,
|
|
58
|
+
raw: body
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
module.exports = {
|
|
63
|
+
upload
|
|
64
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
const path = require("path");
|
|
2
|
+
const { createProgressFilePart } = require("../../utils/file");
|
|
3
|
+
|
|
4
|
+
async function upload(context) {
|
|
5
|
+
const { filePath, headers, http, onProgress } = context;
|
|
6
|
+
const filePart = createProgressFilePart(filePath, onProgress);
|
|
7
|
+
const fileName = encodeURIComponent(path.basename(filePath));
|
|
8
|
+
|
|
9
|
+
let response;
|
|
10
|
+
try {
|
|
11
|
+
response = await http.put(`https://transfer.sh/${fileName}`, filePart.stream, {
|
|
12
|
+
headers: {
|
|
13
|
+
"Content-Type": "application/octet-stream",
|
|
14
|
+
...headers
|
|
15
|
+
},
|
|
16
|
+
maxBodyLength: Infinity,
|
|
17
|
+
responseType: "text",
|
|
18
|
+
transformResponse: [(data) => data]
|
|
19
|
+
});
|
|
20
|
+
} catch (error) {
|
|
21
|
+
if (typeof onProgress === "function") {
|
|
22
|
+
onProgress({
|
|
23
|
+
phase: "error",
|
|
24
|
+
filename: filePart.filename,
|
|
25
|
+
totalBytes: filePart.totalBytes,
|
|
26
|
+
bytesTransferred: 0,
|
|
27
|
+
percent: 0,
|
|
28
|
+
message: error.message
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
throw error;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const raw = String(response.data || "").trim();
|
|
35
|
+
if (!raw || !/^https?:\/\//i.test(raw)) {
|
|
36
|
+
throw new Error(raw || "transfer.sh upload failed.");
|
|
37
|
+
}
|
|
38
|
+
if (typeof onProgress === "function") {
|
|
39
|
+
onProgress({
|
|
40
|
+
phase: "complete",
|
|
41
|
+
filename: filePart.filename,
|
|
42
|
+
totalBytes: filePart.totalBytes,
|
|
43
|
+
bytesTransferred: filePart.totalBytes,
|
|
44
|
+
percent: 100
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
platform: "transfersh",
|
|
50
|
+
success: true,
|
|
51
|
+
url: raw,
|
|
52
|
+
raw
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
module.exports = {
|
|
57
|
+
upload
|
|
58
|
+
};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
const FormData = require("form-data");
|
|
2
|
+
const { createProgressFilePart } = require("../../utils/file");
|
|
3
|
+
|
|
4
|
+
async function upload(context) {
|
|
5
|
+
const { filePath, apiKey, metadata, headers, http, onProgress } = context;
|
|
6
|
+
|
|
7
|
+
if (!apiKey) {
|
|
8
|
+
throw new Error('Missing apiKey for "upfiles". Pass apiKey in client config or upload options.');
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const form = new FormData();
|
|
12
|
+
const filePart = createProgressFilePart(filePath, onProgress);
|
|
13
|
+
form.append("token", apiKey);
|
|
14
|
+
form.append("file", filePart.stream, filePart.filename);
|
|
15
|
+
|
|
16
|
+
for (const [key, value] of Object.entries(metadata || {})) {
|
|
17
|
+
form.append(key, value);
|
|
18
|
+
}
|
|
19
|
+
let response;
|
|
20
|
+
try {
|
|
21
|
+
response = await http.post("https://api.upfiles.com/upload", form, {
|
|
22
|
+
headers: {
|
|
23
|
+
...form.getHeaders(),
|
|
24
|
+
...headers
|
|
25
|
+
},
|
|
26
|
+
maxBodyLength: Infinity
|
|
27
|
+
});
|
|
28
|
+
} catch (error) {
|
|
29
|
+
if (typeof onProgress === "function") {
|
|
30
|
+
onProgress({
|
|
31
|
+
phase: "error",
|
|
32
|
+
filename: filePart.filename,
|
|
33
|
+
totalBytes: filePart.totalBytes,
|
|
34
|
+
bytesTransferred: 0,
|
|
35
|
+
percent: 0,
|
|
36
|
+
message: error.message
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
throw error;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const body = response.data || {};
|
|
43
|
+
const success = body.status === "success" && Boolean(body.url);
|
|
44
|
+
if (!success) {
|
|
45
|
+
throw new Error(body.message || "UpFiles upload failed.");
|
|
46
|
+
}
|
|
47
|
+
if (typeof onProgress === "function") {
|
|
48
|
+
onProgress({
|
|
49
|
+
phase: "complete",
|
|
50
|
+
filename: filePart.filename,
|
|
51
|
+
totalBytes: filePart.totalBytes,
|
|
52
|
+
bytesTransferred: filePart.totalBytes,
|
|
53
|
+
percent: 100
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
platform: "upfiles",
|
|
59
|
+
success: true,
|
|
60
|
+
url: body.url,
|
|
61
|
+
raw: body
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
module.exports = {
|
|
66
|
+
upload
|
|
67
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
const upfiles = require("./provider/upfiles");
|
|
2
|
+
const fileio = require("./provider/fileio");
|
|
3
|
+
const catbox = require("./provider/catbox");
|
|
4
|
+
const transfersh = require("./provider/transfersh");
|
|
5
|
+
|
|
6
|
+
module.exports = {
|
|
7
|
+
upfiles,
|
|
8
|
+
fileio,
|
|
9
|
+
catbox,
|
|
10
|
+
transfersh
|
|
11
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require("./upload/client");
|