e621 1.0.9 → 2.0.0-dev.11

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.
Files changed (50) hide show
  1. package/.node-version +1 -0
  2. package/README.md +116 -187
  3. package/build/package.json +14 -11
  4. package/build/src/index.d.ts +28 -295
  5. package/build/src/index.js +83 -442
  6. package/build/src/modules/Pools.d.ts +120 -0
  7. package/build/src/modules/Pools.js +247 -0
  8. package/build/src/modules/PostSets.d.ts +88 -0
  9. package/build/src/modules/PostSets.js +182 -0
  10. package/build/src/modules/Posts.d.ts +124 -0
  11. package/build/src/modules/Posts.js +323 -0
  12. package/build/src/modules/UserFeedback.d.ts +66 -0
  13. package/build/src/modules/UserFeedback.js +134 -0
  14. package/build/src/modules/Users.d.ts +110 -0
  15. package/build/src/modules/Users.js +248 -0
  16. package/build/src/modules/WikiPages.d.ts +99 -0
  17. package/build/src/modules/WikiPages.js +208 -0
  18. package/build/src/structures/AuthenticatedUser.d.ts +109 -0
  19. package/build/src/structures/AuthenticatedUser.js +128 -0
  20. package/build/src/structures/Pool.d.ts +85 -0
  21. package/build/src/structures/Pool.js +110 -0
  22. package/build/src/structures/PoolHistory.d.ts +42 -0
  23. package/build/src/structures/PoolHistory.js +53 -0
  24. package/build/src/structures/Post.d.ts +147 -0
  25. package/build/src/structures/Post.js +155 -0
  26. package/build/src/structures/PostHistory.d.ts +52 -0
  27. package/build/src/structures/PostHistory.js +93 -0
  28. package/build/src/structures/PostSet.d.ts +71 -0
  29. package/build/src/structures/PostSet.js +91 -0
  30. package/build/src/structures/User.d.ts +62 -0
  31. package/build/src/structures/User.js +80 -0
  32. package/build/src/structures/WikiPage.d.ts +16 -0
  33. package/build/src/structures/WikiPage.js +26 -0
  34. package/build/src/structures/WikiPageHistory.d.ts +37 -0
  35. package/build/src/structures/WikiPageHistory.js +49 -0
  36. package/build/src/types/index.d.ts +92 -0
  37. package/build/src/types/pools.d.ts +60 -0
  38. package/build/src/types/post_sets.d.ts +33 -0
  39. package/build/src/types/posts.d.ts +165 -0
  40. package/build/src/types/user_feedback.d.ts +27 -0
  41. package/build/src/types/users.d.ts +277 -0
  42. package/build/src/types/wiki_pages.d.ts +65 -0
  43. package/build/src/util/FormHelper.d.ts +9 -0
  44. package/build/src/util/FormHelper.js +15 -0
  45. package/build/src/util/MultipartData.d.ts +7 -0
  46. package/build/src/util/MultipartData.js +39 -0
  47. package/build/src/util/RequestHandler.d.ts +37 -0
  48. package/build/src/util/RequestHandler.js +311 -0
  49. package/package.json +14 -11
  50. package/LICENSE +0 -21
@@ -6,459 +6,100 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
6
6
  if (k2 === undefined) k2 = k;
7
7
  o[k2] = m[k];
8
8
  }));
9
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
- Object.defineProperty(o, "default", { enumerable: true, value: v });
11
- }) : function(o, v) {
12
- o["default"] = v;
13
- });
14
- var __importStar = (this && this.__importStar) || function (mod) {
15
- if (mod && mod.__esModule) return mod;
16
- var result = {};
17
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
- __setModuleDefault(result, mod);
19
- return result;
9
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
20
11
  };
21
12
  var __importDefault = (this && this.__importDefault) || function (mod) {
22
13
  return (mod && mod.__esModule) ? mod : { "default": mod };
23
14
  };
24
15
  Object.defineProperty(exports, "__esModule", { value: true });
25
- exports.E621 = exports.APIError = void 0;
16
+ exports.User = exports.PostSet = exports.Post = exports.PoolHistory = exports.Pool = exports.AuthenticatedUser = exports.APIError = void 0;
17
+ const RequestHandler_1 = __importDefault(require("./util/RequestHandler"));
18
+ const Posts_1 = __importDefault(require("./modules/Posts"));
19
+ const UserFeedback_1 = __importDefault(require("./modules/UserFeedback"));
20
+ const Users_1 = __importDefault(require("./modules/Users"));
21
+ const PostSets_1 = __importDefault(require("./modules/PostSets"));
22
+ const Pools_1 = __importDefault(require("./modules/Pools"));
23
+ const AuthenticatedUser_1 = __importDefault(require("./structures/AuthenticatedUser"));
24
+ exports.AuthenticatedUser = AuthenticatedUser_1.default;
25
+ const Pool_1 = __importDefault(require("./structures/Pool"));
26
+ exports.Pool = Pool_1.default;
27
+ const PoolHistory_1 = __importDefault(require("./structures/PoolHistory"));
28
+ exports.PoolHistory = PoolHistory_1.default;
29
+ const Post_1 = __importDefault(require("./structures/Post"));
30
+ exports.Post = Post_1.default;
31
+ const PostSet_1 = __importDefault(require("./structures/PostSet"));
32
+ exports.PostSet = PostSet_1.default;
33
+ const User_1 = __importDefault(require("./structures/User"));
34
+ exports.User = User_1.default;
35
+ const WikiPages_1 = __importDefault(require("./modules/WikiPages"));
26
36
  const package_json_1 = __importDefault(require("../package.json"));
27
- const https = __importStar(require("https"));
28
- class APIError extends Error {
29
- constructor(code, message, method, endpoint) {
30
- super(`Unexpected ${code} ${message} on ${method} ${endpoint}`);
31
- this.name = "APIError";
32
- this.code = code;
33
- this.errmessage = message;
34
- this.method = method;
35
- this.endpoint = endpoint;
36
- switch (code) {
37
- case 400:
38
- this.name = "APIError[BadRequest]";
39
- break;
40
- case 401:
41
- this.name = "APIError[Unauthorized]";
42
- break;
43
- case 403:
44
- this.name = "APIError[Forbidden]";
45
- break;
46
- case 404:
47
- this.name = "APIError[NotFound]";
48
- break;
49
- case 429:
50
- this.name = "APIError[RateLimited]";
51
- break;
52
- }
53
- }
54
- }
55
- exports.APIError = APIError;
37
+ // note for future reference (browser compatibility?)
38
+ // POST with "_method=*" can be used in place of PUT/PATCH/DELETE
56
39
  class E621 {
57
- /**
58
- * Construct an instance of E621
59
- *
60
- * @param {string} [username] - your e621 username to use for requests
61
- * @param {string} [apiKey] - an api key to use for requests
62
- * @param {string[]} [blacklist=[]] - a list of tags to use to filter out posts
63
- * @param {string }[userAgent] - A user agent to use for requests
64
- * @param {boolean} [fixNullURLs=true] - If null urls should be converted to proper urls
65
- * @param {string} [baseDomain=this.baseDomain] - The domain to use for api requests
66
- * @param {boolean} [setHost=false] - If we should set the Host header on requests to e621.net (useful for proxies).
67
- * @example new E621();
68
- * @example new E621("YourUsername", "YourAPIKey");
69
- * @example new E621("YourUsername", "YourAPIKey", ["male/male"]);
70
- * @example new E621("YourUsername", "YourAPIKey", ["male/male"], "MyAwesomeProject/1.0.0");
71
- * @example new E621("YourUsername", "YourAPIKey", ["male/male"], "MyAwesomeProject/1.0.0", false);
72
- * @example new E621("YourUsername", "YourAPIKey", ["male/male"], "MyAwesomeProject/1.0.0", false, "mye621.local");
73
- * @example new E621("YourUsername", "YourAPIKey", ["male/male"], "MyAwesomeProject/1.0.0", false, "mye621.local", false);
74
- */
75
- constructor(username, apiKey, blacklist, userAgent, fixNullURLs, baseDomain, setHost) {
76
- this.username = username || null;
77
- this.apiKey = apiKey || null;
78
- this.blacklist = blacklist || [];
79
- this.userAgent = userAgent || `E621/${package_json_1.default.version} (https://github.com/FurryBotCo/E621)`;
80
- this.fixNullURLs = fixNullURLs ?? true;
81
- this.baseDomain = baseDomain ?? "e621.net";
82
- this.setHost = !!setHost;
83
- }
84
- get auth() {
85
- return this.username && this.apiKey ? Buffer.from(`${this.username}:${this.apiKey}`).toString("base64") : null;
86
- }
87
- /**
88
- * Get posts from e621
89
- *
90
- * @param {string[]} [tags=[]] - The tags to fetch posts for, 40 max
91
- * @param {number} [limit=25] - The, maximum amount of posts to get, 320 max
92
- * @param {number} [page=1] - The page of posts to get, see {@link https://e621.net/help/api#posts_list|E621 API Posts#List}
93
- * @returns {Promise<(Post | NullableURLPost)[]>}
94
- * @example getPosts()
95
- * @example getPosts("male bulge");
96
- * @example getPosts(["male", "bulge"]);
97
- * @example getPosts(["male", "bulge"], 5);
98
- * @example getPosts(["male", "bulge"], 5, 1);
99
- */
100
- async getPosts(tags, limit, page) {
101
- if (tags && !Array.isArray(tags))
102
- tags = tags.split(" ");
103
- if (tags && tags.length > 40)
104
- throw new TypeError("You may only supply up to 40 tags.");
105
- if (limit && limit > 320)
106
- throw new TypeError("You may only request up to 320 posts at a time.");
107
- // eslint-disable-next-line
108
- return new Promise((a, b) => https
109
- .request({
110
- method: "GET",
111
- host: this.baseDomain,
112
- path: `/posts.json?${tags ? `tags=${encodeURIComponent(tags.join(" "))}&` : ""}${limit ? `limit=${limit}&` : ""}${page ? `page=${page}&` : ""}`,
113
- headers: {
114
- "User-Agent": this.userAgent,
115
- ...(this.auth ? {
116
- Authorization: this.auth
117
- } : {}),
118
- ...(this.setHost ? {
119
- Host: "e621.net"
120
- } : {})
121
- }
122
- }, (res) => {
123
- const data = [];
124
- res
125
- .on("data", (d) => data.push(d))
126
- .on("error", b)
127
- .on("end", () => {
128
- if (res.statusCode === undefined)
129
- throw new Error("recieved undefined statusCode");
130
- if (res.statusCode !== 200) {
131
- throw new APIError(res.statusCode, res.statusMessage, "GET", "/posts.json");
132
- }
133
- else {
134
- if (this.fixNullURLs)
135
- return a(this.filterPosts(JSON.parse(Buffer.concat(data).toString()).posts).map(this.fixURL.bind(this)));
136
- else
137
- return a(this.filterPosts(JSON.parse(Buffer.concat(data).toString()).posts));
40
+ request = new RequestHandler_1.default(this);
41
+ postSets = new PostSets_1.default(this);
42
+ pools = new Pools_1.default(this);
43
+ posts = new Posts_1.default(this);
44
+ userFeedback = new UserFeedback_1.default(this);
45
+ users = new Users_1.default(this);
46
+ wikiPages = new WikiPages_1.default(this);
47
+ auth;
48
+ options;
49
+ constructor(options) {
50
+ if (!options)
51
+ options = {};
52
+ if (!options.instanceHost)
53
+ options.instanceHost = "e621.net";
54
+ options.instanceSSL = options.instanceSSL ?? ["e621.net", "yiff.rest"].includes(options.instanceHost);
55
+ if (!options.instancePort)
56
+ options.instancePort = options.instanceSSL ? 443 : 80;
57
+ if (!options.imageReconstructionType) {
58
+ switch (options.instanceHost) {
59
+ case "e621.net":
60
+ options.imageReconstructionType = "e621";
61
+ break;
62
+ case "yiff.rest":
63
+ options.imageReconstructionType = "yiffy";
64
+ break;
65
+ case "e621.local":
66
+ options.imageReconstructionType = "dev";
67
+ break;
68
+ default: {
69
+ options.imageReconstructionType = null;
70
+ if (!options.reconstructStaticURL)
71
+ process.emitWarning("You specified a host that wasn't in our known list (e621.net, yiff.rest, e621.local) and didn't also specify imageReconstructionType or reconstructStaticURL. This WILL cause an error if we see any null file urls.");
138
72
  }
139
- });
140
- })
141
- .end());
142
- }
143
- /**
144
- * Get a specifc post from e621, by id
145
- *
146
- * @param {number} id - The id of the post to get
147
- * @returns {Promise<(Post | NullableURLPost)>}
148
- * @example getPostById(1022094)
149
- */
150
- async getPostById(id) {
151
- if (isNaN(id) || id < 1 || !id)
152
- throw new TypeError("Invalid id provided.");
153
- // eslint-disable-next-line
154
- return new Promise((a, b) => https
155
- .request({
156
- method: "GET",
157
- host: this.baseDomain,
158
- path: `/posts/${id}.json`,
159
- headers: {
160
- "User-Agent": this.userAgent,
161
- ...(this.auth ? {
162
- Authorization: this.auth
163
- } : {}),
164
- ...(this.setHost ? {
165
- Host: "e621.net"
166
- } : {})
167
73
  }
168
- }, (res) => {
169
- const data = [];
170
- res
171
- .on("data", (d) => data.push(d))
172
- .on("error", b)
173
- .on("end", () => {
174
- if (res.statusCode === undefined)
175
- throw new Error("recieved undefined statusCode");
176
- if (res.statusCode !== 200) {
177
- throw new APIError(res.statusCode, res.statusMessage, "GET", `/posts/${id}.json`);
178
- }
179
- else {
180
- if (this.fixNullURLs)
181
- return a(this.fixURL(JSON.parse(Buffer.concat(data).toString()).post));
182
- else
183
- return a(JSON.parse(Buffer.concat(data).toString()).post);
184
- }
185
- });
186
- })
187
- .end());
188
- }
189
- /**
190
- * Get a specifc post from e621, by md5
191
- *
192
- * @param {string} md5 - the md5 of the post to get
193
- * @returns {Promise<(Post | NullableURLPost)>}
194
- * @example getPostByMD5("6fd0b0f2237543bfeee5ca9318a97b46")
195
- */
196
- async getPostByMD5(md5) {
197
- // md5 hashes are always 32 characters
198
- if (!md5 || md5.length !== 32)
199
- throw new TypeError("Invalid md5 provided.");
200
- // eslint-disable-next-line
201
- return new Promise((a, b) => https
202
- .request({
203
- method: "GET",
204
- host: this.baseDomain,
205
- path: `/posts.json?md5=${md5}`,
206
- headers: {
207
- "User-Agent": this.userAgent,
208
- ...(this.auth ? {
209
- Authorization: this.auth
210
- } : {}),
211
- ...(this.setHost ? {
212
- Host: "e621.net"
213
- } : {})
74
+ }
75
+ Object.defineProperties(this, {
76
+ auth: {
77
+ get() {
78
+ return !this.options.authUser || !this.options.authKey ? null : `Basic ${Buffer.from(`${this.options.authUser}:${this.options.authKey}`).toString("base64")}`;
79
+ },
80
+ configurable: false,
81
+ enumerable: false
82
+ },
83
+ options: {
84
+ value: {
85
+ instanceHost: options.instanceHost,
86
+ instancePort: options.instancePort,
87
+ instanceSSL: options.instanceSSL,
88
+ authUser: options.authUser ?? null,
89
+ authKey: options.authKey ?? null,
90
+ reconstructStaticURL: options.reconstructStaticURL || null,
91
+ imageReconstructionType: options.imageReconstructionType || "hierarchy",
92
+ userAgent: options.userAgent ?? `E621/${package_json_1.default.version} (https://github.com/DonovanDMC/E621${!options.authUser ? "" : `; "${options.authUser}"`})`,
93
+ requestTimeout: options.requestTimeout ?? 30
94
+ },
95
+ configurable: false,
96
+ enumerable: false,
97
+ writable: false
214
98
  }
215
- }, (res) => {
216
- const data = [];
217
- res
218
- .on("data", (d) => data.push(d))
219
- .on("error", b)
220
- .on("end", () => {
221
- if (res.statusCode === undefined)
222
- throw new Error("recieved undefined statusCode");
223
- if (res.statusCode !== 200) {
224
- throw new APIError(res.statusCode, res.statusMessage, "GET", `/posts.json?md5=${md5}`);
225
- }
226
- else {
227
- if (this.fixNullURLs)
228
- return a(this.fixURL(JSON.parse(Buffer.concat(data).toString()).post));
229
- else
230
- return a(JSON.parse(Buffer.concat(data).toString()).post);
231
- }
232
- });
233
- })
234
- .end());
235
- }
236
- /**
237
- * Get a specifc post from e621, by md5
238
- *
239
- * @param {number} id - the id of the post to edit
240
- * @param {string} [reason="Edit via https://npm.im/e621"] - The edit reason
241
- * @param {string} [tagChanges] - the tags to change, see {@link https://e621.net/help/api#posts_update|Posts Update Documentation} (list tag to add, list tag with a minus to remove)
242
- * @param {string} [sourceChanges] - the sources to change, see {@link https://e621.net/help/api#posts_update|Posts Update Documentation} (same as above, with sources)
243
- * @param {number} [parentId] - the id of the parent of this image
244
- * @param {string} [description] - the description of this image
245
- * @param {("s"|"q"|"e")} [rating] - the rating of this image
246
- * @param {boolean} [ratingLocked] - if the rating of this image should be locked
247
- * @param {boolean} [noteLocked] - if this image should be note locked
248
- * @param {boolean} [hasEmbeddedNotes] - if this image has embedded notes
249
- * @returns {Promise<(Post | NullableURLPost)>}
250
- * @example editPost(1022094, "I dunno", "dog -cat")
251
- * @example editPost(1022094, "I dunno", undefined, "-https://furaffinity.net/(...) https://inkbunny.net/(...)")
252
- * @example editPost(1022094, "I dunno", undefined, undefined, 1097929)
253
- * @example editPost(1022094, "I dunno", undefined, undefined, undefined, "Some stuff here")
254
- * @example editPost(1022094, "I dunno", undefined, undefined, undefined, undefined, "e")
255
- * @example editPost(1022094, "I dunno", undefined, undefined, undefined, undefined, undefined, true)
256
- * @example editPost(1022094, "I dunno", undefined, undefined, undefined, undefined, undefined, undefined, false)
257
- * @example editPost(1022094, "I dunno", undefined, undefined, undefined, undefined, undefined, undefined, undefined, true)
258
- */
259
- async editPost(id, reason, tagChanges, sourceChanges, parentId, description, rating, ratingLocked, noteLocked, hasEmbeddedNotes) {
260
- if (isNaN(id) || id < 1 || !id)
261
- throw new TypeError("Invalid id provided.");
262
- if (!this.auth)
263
- throw new Error("Authentication is required to use this.");
264
- const p = await this.getPostById(id);
265
- const q = [
266
- `post[edit_reason]=${encodeURIComponent(reason ? reason : "Edit via https://npm.im/e621")}`
267
- ];
268
- if (tagChanges)
269
- q.push(`post[tag_string_diff]=${encodeURIComponent(tagChanges)}`);
270
- if (sourceChanges)
271
- q.push(`post[source_diff]=${encodeURIComponent(sourceChanges)}`);
272
- if (parentId)
273
- q.push(`post[parent_id]=${parentId}`, `post[old_parent_id]=${p.relationships.parent_id ?? "null"}`);
274
- if (description)
275
- q.push(`post[description]=${encodeURIComponent(description)}`, `post[old_description]=${encodeURIComponent(p.description)}`);
276
- if (rating)
277
- q.push(`post[rating]=${rating}`, `post[old_rating]=${p.rating}`);
278
- if (ratingLocked)
279
- q.push(`post[is_rating_locked]=${ratingLocked ? "true" : "false"}`);
280
- if (noteLocked)
281
- q.push(`post[is_note_locked]=${noteLocked ? "true" : "false"}`);
282
- if (hasEmbeddedNotes)
283
- q.push(`post[has_embedded_notes]=${hasEmbeddedNotes ? "true" : "false"}`);
284
- // eslint-disable-next-line
285
- return new Promise((a, b) => {
286
- const req = https
287
- .request({
288
- method: "PATCH",
289
- host: this.baseDomain,
290
- path: `/posts/${id}.json`,
291
- headers: {
292
- "Content-Type": "application/x-www-form-urlencoded",
293
- "User-Agent": this.userAgent,
294
- "Authorization": this.auth,
295
- ...(this.setHost ? {
296
- Host: "e621.net"
297
- } : {})
298
- }
299
- }, (res) => {
300
- const data = [];
301
- res
302
- .on("data", (d) => data.push(d))
303
- .on("error", b)
304
- .on("end", () => {
305
- if (res.statusCode === undefined)
306
- throw new Error("recieved undefined statusCode");
307
- if (res.statusCode !== 200) {
308
- throw new APIError(res.statusCode, res.statusMessage, "PATCH", `/posts/${id}.json`);
309
- }
310
- else {
311
- if (this.fixNullURLs)
312
- return a(this.fixURL(JSON.parse(Buffer.concat(data).toString()).post));
313
- else
314
- return a(JSON.parse(Buffer.concat(data).toString()).post);
315
- }
316
- });
317
- });
318
- req.write(q.join("&"));
319
- req.end();
320
- });
321
- }
322
- /**
323
- *
324
- * @param {string} fileURL - the url of the file to send to Discord
325
- * @param {(string[]|string)} tags - the tags to put on the post -- if you upload a post with less than 4 tags, e621 mods will not like you
326
- * @param {("s"|"q"|"e")} rating - the rating for the image
327
- * @param {(string[]|string)} [sources] - The sources of the image
328
- * @param {string} [description] - A description for the post
329
- * @param {number} [parent] - id of the parent post of this image
330
- * @param {string} [referer] - I dunno
331
- * @param {string} [md5Confirmation] - the md5 of the provided fileURL, to confirm it matches
332
- * @example createPost("https://pbs.twimg.com/media/EbOwnXpXkAIC5ZX.jpg:orig", ["gaokun", "bulge", "penis_outline" (...)], "e")
333
- * @example createPost("https://pbs.twimg.com/media/EbOwnXpXkAIC5ZX.jpg:orig", ["gaokun", "bulge", "penis_outline" (...)], "e", ["https://twitter.com/Gaokunx3", "https://twitter.com/Gaokunx3/status/1275559030522556417"])
334
- * @example createPost("https://pbs.twimg.com/media/EbOwnXpXkAIC5ZX.jpg:orig", ["gaokun", "bulge", "penis_outline" (...)], "e", ["https://twitter.com/Gaokunx3", "https://twitter.com/Gaokunx3/status/1275559030522556417"], "Some Description Stuff Here")
335
- * @example createPost("https://pbs.twimg.com/media/EbOwnXpXkAIC5ZX.jpg:orig", ["gaokun", "bulge", "penis_outline" (...)], "e", ["https://twitter.com/Gaokunx3", "https://twitter.com/Gaokunx3/status/1275559030522556417"], "Some Description Stuff Here", 1234)
336
- * @example createPost("https://pbs.twimg.com/media/EbOwnXpXkAIC5ZX.jpg:orig", ["gaokun", "bulge", "penis_outline" (...)], "e", ["https://twitter.com/Gaokunx3", "https://twitter.com/Gaokunx3/status/1275559030522556417"], "Some Description Stuff Here", 1234, "https://npm.im/e621")
337
- * @example createPost("https://pbs.twimg.com/media/EbOwnXpXkAIC5ZX.jpg:orig", ["gaokun", "bulge", "penis_outline" (...)], "e", ["https://twitter.com/Gaokunx3", "https://twitter.com/Gaokunx3/status/1275559030522556417"], "Some Description Stuff Here", 1234, "https://npm.im/e621", "abcdefghijklmnopqrstuvwxyz123456")
338
- * @returns
339
- */
340
- async createPost(fileURL, tags, rating, sources, description, parent, referer, md5Confirmation) {
341
- if (!this.auth)
342
- throw new Error("Authentication is required to use this.");
343
- const q = [
344
- `upload[direct_url]=${encodeURIComponent(fileURL)}`,
345
- `upload[tag_string]=${encodeURIComponent(Array.isArray(tags) ? tags.join(" ") : tags)}`,
346
- `upload[rating]=${rating}`
347
- ];
348
- if (sources)
349
- q.push(`upload[source]=${encodeURIComponent(Array.isArray(sources) ? sources.join(" ") : sources)}`);
350
- if (description)
351
- q.push(`upload[description]=${encodeURIComponent(description)}`);
352
- if (parent)
353
- q.push(`upload[parent_id]=${parent}`);
354
- if (referer)
355
- q.push(`upload[referer]=${encodeURIComponent(referer)}`);
356
- if (md5Confirmation)
357
- q.push(`upload[md5_confirmation]=${md5Confirmation}`);
358
- // eslint-disable-next-line
359
- return new Promise((a, b) => {
360
- const req = https
361
- .request({
362
- method: "POST",
363
- host: this.baseDomain,
364
- path: "/uploads.json",
365
- headers: {
366
- "Content-Type": "application/x-www-form-urlencoded",
367
- "User-Agent": this.userAgent,
368
- "Authorization": this.auth,
369
- ...(this.setHost ? {
370
- Host: "e621.net"
371
- } : {})
372
- }
373
- }, (res) => {
374
- const data = [];
375
- res
376
- .on("data", (d) => data.push(d))
377
- .on("error", b)
378
- .on("end", () => {
379
- if (res.statusCode === undefined)
380
- throw new Error("recieved undefined statusCode");
381
- if (res.statusCode !== 200) {
382
- throw new APIError(res.statusCode, res.statusMessage, "POST", "/uploads.json");
383
- }
384
- else
385
- return a((JSON.parse(Buffer.concat(data).toString())));
386
- });
387
- });
388
- req.write(q.join("&"));
389
- req.end();
390
- });
391
- }
392
- filterPosts(p) {
393
- return p.filter((v) => !this.blacklist.some((bl) => Object.values(v.tags).reduce((a, b) => a.concat(b), []).includes(bl)));
394
- }
395
- /**
396
- * Convert null urls on a post into proper urls.
397
- *
398
- * @param {NullableURLPost} p - The post to fix
399
- * @returns {Post}
400
- */
401
- fixURL(p) {
402
- if (p.file.url === null)
403
- p.file.url = this.constructURLFromMD5(p.file.md5, p.file.ext, false);
404
- if (p.preview.url === null)
405
- p.preview.url = this.constructURLFromMD5(p.file.md5, p.file.ext, true);
406
- if (p.sample.url === null)
407
- p.sample.url = this.constructURLFromMD5(p.file.md5, p.file.ext, false);
408
- return p;
409
- }
410
- /**
411
- * Construct a url from its md5 counterpart
412
- *
413
- * @param {string} md5 - the md5
414
- * @param {string} [ext="png"] - The extension, assumed png if not provided
415
- * @param {boolean} [preview=false]
416
- */
417
- constructURLFromMD5(md5, ext = "png", preview = false) {
418
- return `https://static1.e621.net/data${preview ? "/preview" : ""}/${md5.slice(0, 2)}/${md5.slice(2, 4)}/${md5}.${ext}`;
419
- }
420
- /**
421
- * Fetch your "upload limit" info (this seems to just be general account info, along with upload limit)
422
- *
423
- * authentication is REQUIRED
424
- *
425
- * @returns {Promise<UploadLimit>}
426
- */
427
- async getUploadLimit() {
428
- return new Promise((a, b) => {
429
- if (!this.auth)
430
- return b("E621#getUploadLimit requires authentication.");
431
- https
432
- .request({
433
- method: "GET",
434
- host: this.baseDomain,
435
- path: "/users/upload_limit.json",
436
- headers: {
437
- "Content-Type": "application/x-www-form-urlencoded",
438
- "User-Agent": this.userAgent,
439
- "Authorization": this.auth,
440
- ...(this.setHost ? {
441
- Host: "e621.net"
442
- } : {})
443
- }
444
- }, (res) => {
445
- const data = [];
446
- res
447
- .on("data", (d) => data.push(d))
448
- .on("error", b)
449
- .on("end", () => {
450
- if (res.statusCode === undefined)
451
- throw new Error("recieved undefined statusCode");
452
- if (res.statusCode !== 200) {
453
- throw new APIError(res.statusCode, res.statusMessage, "GET", "/users/upload_limit.json");
454
- }
455
- else
456
- return a(JSON.parse(Buffer.concat(data).toString()));
457
- });
458
- }).end();
459
99
  });
460
100
  }
461
101
  }
462
- exports.E621 = E621;
463
102
  exports.default = E621;
464
- module.exports = E621;
103
+ var RequestHandler_2 = require("./util/RequestHandler");
104
+ Object.defineProperty(exports, "APIError", { enumerable: true, get: function () { return RequestHandler_2.APIError; } });
105
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQUNBLDJFQUFtRDtBQUNuRCw0REFBb0M7QUFDcEMsMEVBQWtEO0FBQ2xELDREQUFvQztBQUNwQyxrRUFBMEM7QUFDMUMsNERBQW9DO0FBQ3BDLHVGQUErRDtBQW9FdEQsNEJBcEVGLDJCQUFpQixDQW9FRTtBQW5FMUIsNkRBQXFDO0FBbUVULGVBbkVyQixjQUFJLENBbUVxQjtBQWxFaEMsMkVBQW1EO0FBa0VqQixzQkFsRTNCLHFCQUFXLENBa0UyQjtBQWpFN0MsNkRBQXFDO0FBaUVVLGVBakV4QyxjQUFJLENBaUV3QztBQWhFbkQsbUVBQTJDO0FBZ0VVLGtCQWhFOUMsaUJBQU8sQ0FnRThDO0FBL0Q1RCw2REFBcUM7QUErRHlCLGVBL0R2RCxjQUFJLENBK0R1RDtBQTlEbEUsb0VBQTRDO0FBQzVDLG1FQUFrQztBQUVsQyxxREFBcUQ7QUFDckQsaUVBQWlFO0FBQ2pFLE1BQXFCLElBQUk7SUFDeEIsT0FBTyxHQUFHLElBQUksd0JBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNuQyxRQUFRLEdBQUcsSUFBSSxrQkFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzlCLEtBQUssR0FBRyxJQUFJLGVBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN4QixLQUFLLEdBQUcsSUFBSSxlQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDeEIsWUFBWSxHQUFHLElBQUksc0JBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN0QyxLQUFLLEdBQUcsSUFBSSxlQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDeEIsU0FBUyxHQUFHLElBQUksbUJBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNmLElBQUksQ0FBZ0I7SUFDNUIsT0FBTyxDQUFrQjtJQUNsQyxZQUFZLE9BQWlCO1FBQzVCLElBQUksQ0FBQyxP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