booru 2.8.1 → 2.9.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/dist/Constants.d.ts +12 -0
- package/dist/Constants.d.ts.map +1 -1
- package/dist/Constants.js +22 -0
- package/dist/Constants.js.map +1 -1
- package/dist/Utils.d.ts +6 -1
- package/dist/Utils.d.ts.map +1 -1
- package/dist/Utils.js +15 -3
- package/dist/Utils.js.map +1 -1
- package/dist/boorus/Booru.d.ts +26 -1
- package/dist/boorus/Booru.d.ts.map +1 -1
- package/dist/boorus/Booru.js +89 -4
- package/dist/boorus/Booru.js.map +1 -1
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -1
- package/dist/sites.json +29 -14
- package/dist/structures/InternalSearchParameters.d.ts +3 -0
- package/dist/structures/InternalSearchParameters.d.ts.map +1 -1
- package/dist/structures/InternalSearchParameters.js.map +1 -1
- package/dist/structures/Site.d.ts +3 -1
- package/dist/structures/Site.d.ts.map +1 -1
- package/dist/structures/Site.js +3 -0
- package/dist/structures/Site.js.map +1 -1
- package/dist/structures/SiteApi.d.ts +2 -0
- package/dist/structures/SiteApi.d.ts.map +1 -1
- package/dist/structures/SiteApi.js.map +1 -1
- package/dist/structures/SiteInfo.d.ts +3 -1
- package/dist/structures/SiteInfo.d.ts.map +1 -1
- package/dist/structures/SiteInfo.js.map +1 -1
- package/package.json +7 -7
package/dist/Constants.d.ts
CHANGED
|
@@ -36,6 +36,18 @@ export declare const USER_AGENT: string;
|
|
|
36
36
|
* @param {BooryCredentials} [credentials] The credentials to use for the search, appended to the querystring
|
|
37
37
|
*/
|
|
38
38
|
export declare function searchURI(site: Site, tags?: string[], limit?: number, page?: number, credentials?: BooruCredentials): string;
|
|
39
|
+
/**
|
|
40
|
+
* Create a full uri to search with
|
|
41
|
+
*
|
|
42
|
+
* @private
|
|
43
|
+
* @param {string} domain The domain to search
|
|
44
|
+
* @param {Site} site The site to search
|
|
45
|
+
* @param {string[]} [tags=[]] The tags to search for
|
|
46
|
+
* @param {number} [limit=100] The limit for images to return
|
|
47
|
+
* @param {number} [page=0] The page to get
|
|
48
|
+
* @param {BooryCredentials} [credentials] The credentials to use for the search, appended to the querystring
|
|
49
|
+
*/
|
|
50
|
+
export declare function postCountURI(site: Site, tags?: string[], limit?: number, credentials?: BooruCredentials): string;
|
|
39
51
|
export declare function tagListURI(site: Site, limit?: number, page?: number, credentials?: BooruCredentials): string;
|
|
40
52
|
/**
|
|
41
53
|
* The default options to use for requests
|
package/dist/Constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Constants.d.ts","sourceRoot":"","sources":["../src/Constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;AACzC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AACtD,OAAO,KAAK,IAAI,MAAM,mBAAmB,CAAA;AACzC,OAAO,KAAK,QAAQ,MAAM,uBAAuB,CAAA;AAMjD,MAAM,MAAM,OAAO,GACf,UAAU,GACV,UAAU,GACV,cAAc,GACd,oBAAoB,GACpB,cAAc,GACd,cAAc,GACd,UAAU,GACV,cAAc,GACd,YAAY,GACZ,eAAe,GACf,UAAU,GACV,YAAY,GACZ,mBAAmB,GACnB,gBAAgB,GAChB,eAAe,CAAA;AAgBnB;;GAEG;AACH,eAAO,MAAM,KAAK,EAAe,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;AAE1D;;;;GAIG;AACH,qBAAa,UAAW,SAAQ,KAAK;gBACvB,OAAO,EAAE,MAAM,GAAG,KAAK;CAWpC;AAED;;;GAGG;AACH,eAAO,MAAM,UAAU,QAAyE,CAAA;AAYhG;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,IAAI,EACV,IAAI,GAAE,MAAM,EAAO,EACnB,KAAK,SAAM,EACX,IAAI,SAAI,EACR,WAAW,GAAE,gBAAqB,GACjC,MAAM,CAcR;AAED,wBAAgB,UAAU,CACxB,IAAI,EAAE,IAAI,EACV,KAAK,SAAM,EACX,IAAI,SAAI,EACR,WAAW,GAAE,gBAAqB,GACjC,MAAM,CAQR;AAED;;;;;GAKG;AACH,eAAO,MAAM,cAAc,EAAE,WAK5B,CAAA"}
|
|
1
|
+
{"version":3,"file":"Constants.d.ts","sourceRoot":"","sources":["../src/Constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAA;AACzC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AACtD,OAAO,KAAK,IAAI,MAAM,mBAAmB,CAAA;AACzC,OAAO,KAAK,QAAQ,MAAM,uBAAuB,CAAA;AAMjD,MAAM,MAAM,OAAO,GACf,UAAU,GACV,UAAU,GACV,cAAc,GACd,oBAAoB,GACpB,cAAc,GACd,cAAc,GACd,UAAU,GACV,cAAc,GACd,YAAY,GACZ,eAAe,GACf,UAAU,GACV,YAAY,GACZ,mBAAmB,GACnB,gBAAgB,GAChB,eAAe,CAAA;AAgBnB;;GAEG;AACH,eAAO,MAAM,KAAK,EAAe,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAA;AAE1D;;;;GAIG;AACH,qBAAa,UAAW,SAAQ,KAAK;gBACvB,OAAO,EAAE,MAAM,GAAG,KAAK;CAWpC;AAED;;;GAGG;AACH,eAAO,MAAM,UAAU,QAAyE,CAAA;AAYhG;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,IAAI,EACV,IAAI,GAAE,MAAM,EAAO,EACnB,KAAK,SAAM,EACX,IAAI,SAAI,EACR,WAAW,GAAE,gBAAqB,GACjC,MAAM,CAcR;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,IAAI,EACV,IAAI,GAAE,MAAM,EAAO,EACnB,KAAK,SAAI,EACT,WAAW,GAAE,gBAAqB,GACjC,MAAM,CAaR;AAED,wBAAgB,UAAU,CACxB,IAAI,EAAE,IAAI,EACV,KAAK,SAAM,EACX,IAAI,SAAI,EACR,WAAW,GAAE,gBAAqB,GACjC,MAAM,CAQR;AAED;;;;;GAKG;AACH,eAAO,MAAM,cAAc,EAAE,WAK5B,CAAA"}
|
package/dist/Constants.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.defaultOptions = exports.USER_AGENT = exports.BooruError = exports.sites = void 0;
|
|
8
8
|
exports.searchURI = searchURI;
|
|
9
|
+
exports.postCountURI = postCountURI;
|
|
9
10
|
exports.tagListURI = tagListURI;
|
|
10
11
|
const Utils_1 = require("./Utils");
|
|
11
12
|
const siteJson = require('./sites.json');
|
|
@@ -73,6 +74,27 @@ function searchURI(site, tags = [], limit = 100, page = 0, credentials = {}) {
|
|
|
73
74
|
});
|
|
74
75
|
return `http${site.insecure ? '' : 's'}://${site.domain}${site.api.search}${query}`;
|
|
75
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
* Create a full uri to search with
|
|
79
|
+
*
|
|
80
|
+
* @private
|
|
81
|
+
* @param {string} domain The domain to search
|
|
82
|
+
* @param {Site} site The site to search
|
|
83
|
+
* @param {string[]} [tags=[]] The tags to search for
|
|
84
|
+
* @param {number} [limit=100] The limit for images to return
|
|
85
|
+
* @param {number} [page=0] The page to get
|
|
86
|
+
* @param {BooryCredentials} [credentials] The credentials to use for the search, appended to the querystring
|
|
87
|
+
*/
|
|
88
|
+
function postCountURI(site, tags = [], limit = 1, credentials = {}) {
|
|
89
|
+
const query = (0, Utils_1.querystring)({
|
|
90
|
+
[site.tagQuery]: expandTags(tags),
|
|
91
|
+
limit,
|
|
92
|
+
...credentials,
|
|
93
|
+
}, {
|
|
94
|
+
arrayJoin: site.tagJoin,
|
|
95
|
+
});
|
|
96
|
+
return `http${site.insecure ? '' : 's'}://${site.domain}${site.api.postCount}${query}`;
|
|
97
|
+
}
|
|
76
98
|
function tagListURI(site, limit = 100, page = 0, credentials = {}) {
|
|
77
99
|
const query = (0, Utils_1.querystring)({
|
|
78
100
|
limit,
|
package/dist/Constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Constants.js","sourceRoot":"","sources":["../src/Constants.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AA6FH,8BAoBC;AAED,gCAaC;
|
|
1
|
+
{"version":3,"file":"Constants.js","sourceRoot":"","sources":["../src/Constants.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AA6FH,8BAoBC;AAaD,oCAkBC;AAED,gCAaC;AAzJD,mCAAqC;AAErC,MAAM,QAAQ,GAAG,OAAO,CAAC,cAAc,CAAC,CAAA;AACxC,MAAM,WAAW,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAA;AA2B9C,MAAM,YAAY,GAAY;IAC5B,UAAU,EAAE,iBAAiB;IAC7B,UAAU,EAAE,qBAAqB;IACjC,UAAU,EAAE,aAAa;CAC1B,CAAA;AAED;;GAEG;AACU,QAAA,KAAK,GAAG,QAAqC,CAAA;AAE1D;;;;GAIG;AACH,MAAa,UAAW,SAAQ,KAAK;IACnC,YAAY,OAAuB;QACjC,KAAK,CAAC,OAAO,YAAY,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAA;QAE3D,IAAI,OAAO,YAAY,KAAK,EAAE,CAAC;YAC7B,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,YAAY,CAAA;QAC5C,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,UAAU,CAAC,CAAA;QAC3C,CAAC;QAED,IAAI,CAAC,IAAI,GAAG,YAAY,CAAA;IAC1B,CAAC;CACF;AAZD,gCAYC;AAED;;;GAGG;AACU,QAAA,UAAU,GAAG,SAAS,WAAW,CAAC,OAAO,0CAA0C,CAAA;AAEhG;;;;;GAKG;AACH,SAAS,UAAU,CAAC,IAAc;IAChC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;AAC5D,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAgB,SAAS,CACvB,IAAU,EACV,OAAiB,EAAE,EACnB,KAAK,GAAG,GAAG,EACX,IAAI,GAAG,CAAC,EACR,cAAgC,EAAE;IAElC,MAAM,KAAK,GAAG,IAAA,mBAAW,EACvB;QACE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,UAAU,CAAC,IAAI,CAAC;QACjC,KAAK;QACL,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI;QACrB,GAAG,WAAW;KACf,EACD;QACE,SAAS,EAAE,IAAI,CAAC,OAAO;KACxB,CACF,CAAA;IAED,OAAO,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,KAAK,EAAE,CAAA;AACrF,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAgB,YAAY,CAC1B,IAAU,EACV,OAAiB,EAAE,EACnB,KAAK,GAAG,CAAC,EACT,cAAgC,EAAE;IAElC,MAAM,KAAK,GAAG,IAAA,mBAAW,EACvB;QACE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,UAAU,CAAC,IAAI,CAAC;QACjC,KAAK;QACL,GAAG,WAAW;KACf,EACD;QACE,SAAS,EAAE,IAAI,CAAC,OAAO;KACxB,CACF,CAAA;IAED,OAAO,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,GAAG,KAAK,EAAE,CAAA;AACxF,CAAC;AAED,SAAgB,UAAU,CACxB,IAAU,EACV,KAAK,GAAG,GAAG,EACX,IAAI,GAAG,CAAC,EACR,cAAgC,EAAE;IAElC,MAAM,KAAK,GAAG,IAAA,mBAAW,EAAC;QACxB,KAAK;QACL,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI;QACrB,GAAG,WAAW;KACf,CAAC,CAAA;IAEF,OAAO,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,GAAG,KAAK,EAAE,CAAA;AACtF,CAAC;AAED;;;;;GAKG;AACU,QAAA,cAAc,GAAgB;IACzC,OAAO,EAAE;QACP,MAAM,EAAE,oDAAoD;QAC5D,YAAY,EAAE,kBAAU;KACzB;CACF,CAAA","sourcesContent":["/**\n * @packageDocumentation\n * @module Constants\n */\n\nimport type { RequestInit } from 'undici'\nimport type { BooruCredentials } from './boorus/Booru'\nimport type Site from './structures/Site'\nimport type SiteInfo from './structures/SiteInfo'\nimport { querystring } from './Utils'\n\nconst siteJson = require('./sites.json')\nconst packageJson = require('../package.json')\n\nexport type AnySite =\n | 'e621.net'\n | 'e926.net'\n | 'hypnohub.net'\n | 'danbooru.donmai.us'\n | 'konachan.com'\n | 'konachan.net'\n | 'yande.re'\n | 'gelbooru.com'\n | 'rule34.xxx'\n | 'safebooru.org'\n | 'tbib.org'\n | 'xbooru.com'\n | 'rule34.paheal.net'\n | 'derpibooru.org'\n | 'realbooru.com'\n\ntype gelTags = {\n 'rating:e': 'rating:explicit'\n 'rating:q': 'rating:questionable'\n 'rating:s': 'rating:safe'\n\n [key: string]: string\n}\n\nconst expandedTags: gelTags = {\n 'rating:e': 'rating:explicit',\n 'rating:q': 'rating:questionable',\n 'rating:s': 'rating:safe',\n}\n\n/**\n * A map of site url/{@link SiteInfo}\n */\nexport const sites = siteJson as Record<AnySite, SiteInfo>\n\n/**\n * Custom error type for when the boorus error or for user-side error, not my code (probably)\n * <p>The name of the error is 'BooruError'\n * @type {Error}\n */\nexport class BooruError extends Error {\n constructor(message: string | Error) {\n super(message instanceof Error ? message.message : message)\n\n if (message instanceof Error) {\n this.stack = message.stack ?? '<No Stack>'\n } else {\n Error.captureStackTrace(this, BooruError)\n }\n\n this.name = 'BooruError'\n }\n}\n\n/**\n * The user-agent to use for searches\n * @private\n */\nexport const USER_AGENT = `booru/${packageJson.version} (+https://github.com/AtoraSuunva/booru)`\n\n/**\n * Expands tags based on a simple map, used for gelbooru/safebooru/etc compat :(\n *\n * @private\n * @param {String[]} tags The tags to expand\n */\nfunction expandTags(tags: string[]): string[] {\n return tags.map((v) => expandedTags[v.toLowerCase()] ?? v)\n}\n\n/**\n * Create a full uri to search with\n *\n * @private\n * @param {string} domain The domain to search\n * @param {Site} site The site to search\n * @param {string[]} [tags=[]] The tags to search for\n * @param {number} [limit=100] The limit for images to return\n * @param {number} [page=0] The page to get\n * @param {BooryCredentials} [credentials] The credentials to use for the search, appended to the querystring\n */\nexport function searchURI(\n site: Site,\n tags: string[] = [],\n limit = 100,\n page = 0,\n credentials: BooruCredentials = {},\n): string {\n const query = querystring(\n {\n [site.tagQuery]: expandTags(tags),\n limit,\n [site.paginate]: page,\n ...credentials,\n },\n {\n arrayJoin: site.tagJoin,\n },\n )\n\n return `http${site.insecure ? '' : 's'}://${site.domain}${site.api.search}${query}`\n}\n\n/**\n * Create a full uri to search with\n *\n * @private\n * @param {string} domain The domain to search\n * @param {Site} site The site to search\n * @param {string[]} [tags=[]] The tags to search for\n * @param {number} [limit=100] The limit for images to return\n * @param {number} [page=0] The page to get\n * @param {BooryCredentials} [credentials] The credentials to use for the search, appended to the querystring\n */\nexport function postCountURI(\n site: Site,\n tags: string[] = [],\n limit = 1,\n credentials: BooruCredentials = {},\n): string {\n const query = querystring(\n {\n [site.tagQuery]: expandTags(tags),\n limit,\n ...credentials,\n },\n {\n arrayJoin: site.tagJoin,\n },\n )\n\n return `http${site.insecure ? '' : 's'}://${site.domain}${site.api.postCount}${query}`\n}\n\nexport function tagListURI(\n site: Site,\n limit = 100,\n page = 0,\n credentials: BooruCredentials = {},\n): string {\n const query = querystring({\n limit,\n [site.paginate]: page,\n ...credentials,\n })\n\n return `http${site.insecure ? '' : 's'}://${site.domain}${site.api.tagList}${query}`\n}\n\n/**\n * The default options to use for requests\n * <p>I could document this better but meh\n *\n * @private\n */\nexport const defaultOptions: RequestInit = {\n headers: {\n Accept: 'application/json, application/xml;q=0.9, */*;q=0.8',\n 'User-Agent': USER_AGENT,\n },\n}\n"]}
|
package/dist/Utils.d.ts
CHANGED
|
@@ -3,6 +3,11 @@
|
|
|
3
3
|
* @module Utils
|
|
4
4
|
*/
|
|
5
5
|
import { type AnySite } from './Constants';
|
|
6
|
+
export interface ParseBooruResult {
|
|
7
|
+
posts: object[];
|
|
8
|
+
count: number;
|
|
9
|
+
offset: number;
|
|
10
|
+
}
|
|
6
11
|
/**
|
|
7
12
|
* Check if `site` is a supported site (and check if it's an alias and return the sites's true name)
|
|
8
13
|
*
|
|
@@ -17,7 +22,7 @@ export declare function resolveSite(domain: string): AnySite | null;
|
|
|
17
22
|
* @param {String} xml The xml to convert to json
|
|
18
23
|
* @return {Object[]} A Promise with an array of objects created from the xml
|
|
19
24
|
*/
|
|
20
|
-
export declare function jsonifyPosts(xml: string):
|
|
25
|
+
export declare function jsonifyPosts(xml: string): ParseBooruResult;
|
|
21
26
|
/**
|
|
22
27
|
* Parses tags xml to json, which can be used with js
|
|
23
28
|
*
|
package/dist/Utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Utils.d.ts","sourceRoot":"","sources":["../src/Utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,KAAK,OAAO,EAAqB,MAAM,aAAa,CAAA;AAE7D;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAkB1D;
|
|
1
|
+
{"version":3,"file":"Utils.d.ts","sourceRoot":"","sources":["../src/Utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,KAAK,OAAO,EAAqB,MAAM,aAAa,CAAA;AAE7D,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAkB1D;AAoCD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,gBAAgB,CA+C1D;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CA+BjD;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAMpE;AAED;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,CAe1C;AAGD;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAIxD;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,GAAG,MAAM,GACrB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAejC;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAItE;AAED,KAAK,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAA;AAC7C,KAAK,UAAU,GAAG,YAAY,GAAG,YAAY,EAAE,CAAA;AAE/C,UAAU,kBAAkB;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,UAAU,0BAA0B;IAClC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,EACjC,EAAE,SAAe,EAAE,GAAE,kBAAuB,GAC3C,MAAM,CASR;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,UAAU,EACjB,EAAE,SAAe,EAAE,GAAE,0BAA+B,GACnD,MAAM,CAMR"}
|
package/dist/Utils.js
CHANGED
|
@@ -64,13 +64,25 @@ function jsonifyPosts(xml) {
|
|
|
64
64
|
}
|
|
65
65
|
throw new Constants_1.BooruError(`The Booru sent back an error: '${message.join(': ')}'`);
|
|
66
66
|
}
|
|
67
|
+
if (data.error) {
|
|
68
|
+
throw new Constants_1.BooruError(`The Booru sent back an error: '${data.error}'`);
|
|
69
|
+
}
|
|
70
|
+
let extractedPosts = [];
|
|
67
71
|
if (data.posts.post) {
|
|
68
|
-
|
|
72
|
+
extractedPosts = data.posts.post;
|
|
69
73
|
}
|
|
70
74
|
if (data.posts.tag) {
|
|
71
|
-
|
|
75
|
+
extractedPosts = Array.isArray(data.posts.tag)
|
|
76
|
+
? data.posts.tag
|
|
77
|
+
: [data.posts.tag];
|
|
72
78
|
}
|
|
73
|
-
|
|
79
|
+
const count = Number(data.posts.count) || 0;
|
|
80
|
+
const offset = Number(data.posts.offset) || 0;
|
|
81
|
+
return {
|
|
82
|
+
posts: extractedPosts,
|
|
83
|
+
count,
|
|
84
|
+
offset,
|
|
85
|
+
};
|
|
74
86
|
}
|
|
75
87
|
/**
|
|
76
88
|
* Parses tags xml to json, which can be used with js
|
package/dist/Utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Utils.js","sourceRoot":"","sources":["../src/Utils.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @packageDocumentation\n * @module Utils\n */\n\nimport { XMLParser } from 'fast-xml-parser'\nimport { type AnySite, BooruError, sites } from './Constants'\n\n/**\n * Check if `site` is a supported site (and check if it's an alias and return the sites's true name)\n *\n * @param {String} domain The site to resolveSite\n * @return {String?} null if site is not supported, the site otherwise\n */\nexport function resolveSite(domain: string): AnySite | null {\n if (typeof domain !== 'string') {\n return null\n }\n\n const lowerDomain = domain.toLowerCase()\n\n for (const [site, info] of Object.entries(sites)) {\n if (\n site === lowerDomain ||\n info.domain === lowerDomain ||\n info.aliases.includes(lowerDomain)\n ) {\n return site as AnySite\n }\n }\n\n return null\n}\n\ninterface XMLPage {\n html: any\n}\n\ninterface XMLPosts {\n post?: any[]\n tag?: any\n}\n\ninterface XMLTags {\n tag?: any[]\n}\n\ninterface BooruXML {\n html?: XMLPage\n '!doctype'?: XMLPage\n}\n\ninterface BooruXMLPosts extends BooruXML {\n posts: XMLPosts\n}\n\ninterface BooruXMLTags extends BooruXML {\n tags: XMLTags\n}\n\nconst xmlParser = new XMLParser({\n ignoreAttributes: false,\n attributeNamePrefix: '',\n})\n\n/**\n * Parses posts xml to json, which can be used with js\n *\n * @private\n * @param {String} xml The xml to convert to json\n * @return {Object[]} A Promise with an array of objects created from the xml\n */\nexport function jsonifyPosts(xml: string): object[] {\n if (typeof xml === 'object') return xml\n\n const data = xmlParser.parse(xml) as BooruXMLPosts\n\n if (data.html || data['!doctype']) {\n // Some boorus return HTML error pages instead of JSON responses on errors\n // So try scraping off what we can in that case\n const page = data.html ?? data['!doctype']?.html\n const message = []\n if (page.body.h1) {\n message.push(page.body.h1)\n }\n\n if (page.body.p) {\n message.push(page.body.p['#text'])\n }\n\n throw new BooruError(\n `The Booru sent back an error: '${message.join(': ')}'`,\n )\n }\n\n if (data.posts.post) {\n return data.posts.post\n }\n\n if (data.posts.tag) {\n return Array.isArray(data.posts.tag) ? data.posts.tag : [data.posts.tag]\n }\n\n return []\n}\n\n/**\n * Parses tags xml to json, which can be used with js\n *\n * @private\n * @param {String} xml The xml to convert to json\n * @return {Object[]} A Promise with an array of objects created from the xml\n */\nexport function jsonifyTags(xml: string): object[] {\n if (typeof xml === 'object') return xml\n\n const data = xmlParser.parse(xml) as BooruXMLTags\n\n if (data.html || data['!doctype']) {\n // Some boorus return HTML error pages instead of JSON responses on errors\n // So try scraping off what we can in that case\n const page = data.html ?? data['!doctype']?.html\n const message = []\n if (page.body.h1) {\n message.push(page.body.h1)\n }\n\n if (page.body.p) {\n message.push(page.body.p['#text'])\n }\n\n throw new BooruError(\n `The Booru sent back an error: '${message.join(': ')}'`,\n )\n }\n\n if (data.tags.tag) {\n return data.tags.tag\n ? Array.isArray(data.tags.tag)\n ? data.tags.tag\n : [data.tags.tag]\n : []\n }\n return []\n}\n\n/**\n * Try to parse JSON, and then return an empty array if data is an empty string, or the parsed JSON\n *\n * Blame rule34.xxx for returning literally an empty response with HTTP 200 for this\n * @param data The data to try and parse\n * @returns Either the parsed data, or an empty array\n */\nexport function tryParseJSON(data: string): Record<string, unknown>[] {\n if (data === '') {\n return []\n }\n\n return JSON.parse(data)\n}\n\n/**\n * Yay fisher-bates\n * Taken from http://stackoverflow.com/a/2450976\n *\n * @private\n * @param {Array} array Array of something\n * @return {Array} Shuffled array of something\n */\nexport function shuffle<T>(array: T[]): T[] {\n let currentIndex: number = array.length\n let temporaryValue: T\n let randomIndex: number\n\n while (currentIndex !== 0) {\n randomIndex = Math.floor(Math.random() * currentIndex)\n currentIndex -= 1\n\n temporaryValue = array[currentIndex]\n array[currentIndex] = array[randomIndex]\n array[randomIndex] = temporaryValue\n }\n\n return array\n}\n\n// Thanks mdn and damnit derpibooru\n/**\n * Generate a random int between [min, max]\n *\n * @private\n * @param {Number} min The minimum (inclusive)\n * @param {Number} max The maximum (inclusive)\n */\nexport function randInt(min: number, max: number): number {\n const nmin = Math.ceil(min)\n const nmax = Math.floor(max)\n return Math.floor(Math.random() * (nmax - nmin + 1)) + nmin\n}\n\n/**\n * Performs some basic search validation\n *\n * @private\n * @param {String} site The site to resolve\n * @param {Number|String} limit The limit for the amount of images to fetch\n */\nexport function validateSearchParams(\n site: string,\n limit: number | string,\n): { site: string; limit: number } {\n const resolvedSite = resolveSite(site)\n\n const resolvedLimit =\n typeof limit !== 'number' ? Number.parseInt(limit, 10) : limit\n\n if (resolvedSite === null) {\n throw new BooruError('Site not supported')\n }\n\n if (typeof limit !== 'number' || Number.isNaN(limit)) {\n throw new BooruError('`limit` should be an int')\n }\n\n return { site: resolvedSite, limit: resolvedLimit }\n}\n\n/**\n * Finds the matching strings between two arrays\n *\n * @private\n * @param {String[]} arr1 The first array\n * @param {String[]} arr2 The second array\n * @return {String[]} The shared strings between the arrays\n */\nexport function compareArrays(arr1: string[], arr2: string[]): string[] {\n return arr1.filter((e1) =>\n arr2.some((e2) => e1.toLowerCase() === e2.toLowerCase()),\n )\n}\n\ntype URIEncodable = string | number | boolean\ntype QueryValue = URIEncodable | URIEncodable[]\n\ninterface QuerystringOptions {\n arrayJoin?: string\n}\n\ninterface EncodeURIQueryValueOptions {\n arrayJoin?: string\n}\n\n/**\n * Turns an object into a query string, correctly encoding uri components\n *\n * @example\n * const options = { page: 10, limit: 100 }\n * const query = querystring(options) // 'page=10&limit=100'\n * console.log(`https://example.com?${query}`)\n *\n * @param query An object with key/value pairs that will be turned into a string\n * @returns A string that can be appended to a url (after `?`)\n */\nexport function querystring(\n query: Record<string, QueryValue>,\n { arrayJoin = '+' }: QuerystringOptions = {},\n): string {\n return Object.entries(query)\n .map(\n ([key, value]) =>\n `${encodeURIComponent(key)}=${encodeURIQueryValue(value, {\n arrayJoin,\n })}`,\n )\n .join('&')\n}\n\n/**\n * Encodes a single value or an array of values to be usable in as a URI component,\n * joining array elements with '+'\n * @param value The value to encode\n * @returns An encoded value that can be passed to a querystring\n */\nexport function encodeURIQueryValue(\n value: QueryValue,\n { arrayJoin = '+' }: EncodeURIQueryValueOptions = {},\n): string {\n if (Array.isArray(value)) {\n return value.map(encodeURIComponent).join(arrayJoin)\n }\n\n return encodeURIComponent(value)\n}\n"]}
|
|
1
|
+
{"version":3,"file":"Utils.js","sourceRoot":"","sources":["../src/Utils.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @packageDocumentation\n * @module Utils\n */\n\nimport { XMLParser } from 'fast-xml-parser'\nimport { type AnySite, BooruError, sites } from './Constants'\n\nexport interface ParseBooruResult {\n posts: object[]\n count: number\n offset: number\n}\n\n/**\n * Check if `site` is a supported site (and check if it's an alias and return the sites's true name)\n *\n * @param {String} domain The site to resolveSite\n * @return {String?} null if site is not supported, the site otherwise\n */\nexport function resolveSite(domain: string): AnySite | null {\n if (typeof domain !== 'string') {\n return null\n }\n\n const lowerDomain = domain.toLowerCase()\n\n for (const [site, info] of Object.entries(sites)) {\n if (\n site === lowerDomain ||\n info.domain === lowerDomain ||\n info.aliases.includes(lowerDomain)\n ) {\n return site as AnySite\n }\n }\n\n return null\n}\n\ninterface XMLPage {\n html: any\n}\n\ninterface XMLPosts {\n post?: any[]\n tag?: any\n count?: number\n offset?: number\n}\n\ninterface XMLTags {\n tag?: any[]\n}\n\ninterface BooruXML {\n html?: XMLPage\n '!doctype'?: XMLPage\n}\n\ninterface BooruXMLPosts extends BooruXML {\n posts: XMLPosts\n error?: string\n}\n\ninterface BooruXMLTags extends BooruXML {\n tags: XMLTags\n}\n\nconst xmlParser = new XMLParser({\n ignoreAttributes: false,\n attributeNamePrefix: '',\n})\n\n/**\n * Parses posts xml to json, which can be used with js\n *\n * @private\n * @param {String} xml The xml to convert to json\n * @return {Object[]} A Promise with an array of objects created from the xml\n */\nexport function jsonifyPosts(xml: string): ParseBooruResult {\n if (typeof xml === 'object') return xml\n\n const data = xmlParser.parse(xml) as BooruXMLPosts\n\n if (data.html || data['!doctype']) {\n // Some boorus return HTML error pages instead of JSON responses on errors\n // So try scraping off what we can in that case\n const page = data.html ?? data['!doctype']?.html\n const message = []\n if (page.body.h1) {\n message.push(page.body.h1)\n }\n\n if (page.body.p) {\n message.push(page.body.p['#text'])\n }\n\n throw new BooruError(\n `The Booru sent back an error: '${message.join(': ')}'`,\n )\n }\n\n if (data.error) {\n throw new BooruError(`The Booru sent back an error: '${data.error}'`)\n }\n\n let extractedPosts: object[] = []\n\n if (data.posts.post) {\n extractedPosts = data.posts.post\n }\n\n if (data.posts.tag) {\n extractedPosts = Array.isArray(data.posts.tag)\n ? data.posts.tag\n : [data.posts.tag]\n }\n\n const count = Number(data.posts.count) || 0\n const offset = Number(data.posts.offset) || 0\n\n return {\n posts: extractedPosts,\n count,\n offset,\n }\n}\n\n/**\n * Parses tags xml to json, which can be used with js\n *\n * @private\n * @param {String} xml The xml to convert to json\n * @return {Object[]} A Promise with an array of objects created from the xml\n */\nexport function jsonifyTags(xml: string): object[] {\n if (typeof xml === 'object') return xml\n\n const data = xmlParser.parse(xml) as BooruXMLTags\n\n if (data.html || data['!doctype']) {\n // Some boorus return HTML error pages instead of JSON responses on errors\n // So try scraping off what we can in that case\n const page = data.html ?? data['!doctype']?.html\n const message = []\n if (page.body.h1) {\n message.push(page.body.h1)\n }\n\n if (page.body.p) {\n message.push(page.body.p['#text'])\n }\n\n throw new BooruError(\n `The Booru sent back an error: '${message.join(': ')}'`,\n )\n }\n\n if (data.tags.tag) {\n return data.tags.tag\n ? Array.isArray(data.tags.tag)\n ? data.tags.tag\n : [data.tags.tag]\n : []\n }\n return []\n}\n\n/**\n * Try to parse JSON, and then return an empty array if data is an empty string, or the parsed JSON\n *\n * Blame rule34.xxx for returning literally an empty response with HTTP 200 for this\n * @param data The data to try and parse\n * @returns Either the parsed data, or an empty array\n */\nexport function tryParseJSON(data: string): Record<string, unknown>[] {\n if (data === '') {\n return []\n }\n\n return JSON.parse(data)\n}\n\n/**\n * Yay fisher-bates\n * Taken from http://stackoverflow.com/a/2450976\n *\n * @private\n * @param {Array} array Array of something\n * @return {Array} Shuffled array of something\n */\nexport function shuffle<T>(array: T[]): T[] {\n let currentIndex: number = array.length\n let temporaryValue: T\n let randomIndex: number\n\n while (currentIndex !== 0) {\n randomIndex = Math.floor(Math.random() * currentIndex)\n currentIndex -= 1\n\n temporaryValue = array[currentIndex]\n array[currentIndex] = array[randomIndex]\n array[randomIndex] = temporaryValue\n }\n\n return array\n}\n\n// Thanks mdn and damnit derpibooru\n/**\n * Generate a random int between [min, max]\n *\n * @private\n * @param {Number} min The minimum (inclusive)\n * @param {Number} max The maximum (inclusive)\n */\nexport function randInt(min: number, max: number): number {\n const nmin = Math.ceil(min)\n const nmax = Math.floor(max)\n return Math.floor(Math.random() * (nmax - nmin + 1)) + nmin\n}\n\n/**\n * Performs some basic search validation\n *\n * @private\n * @param {String} site The site to resolve\n * @param {Number|String} limit The limit for the amount of images to fetch\n */\nexport function validateSearchParams(\n site: string,\n limit: number | string,\n): { site: string; limit: number } {\n const resolvedSite = resolveSite(site)\n\n const resolvedLimit =\n typeof limit !== 'number' ? Number.parseInt(limit, 10) : limit\n\n if (resolvedSite === null) {\n throw new BooruError('Site not supported')\n }\n\n if (typeof limit !== 'number' || Number.isNaN(limit)) {\n throw new BooruError('`limit` should be an int')\n }\n\n return { site: resolvedSite, limit: resolvedLimit }\n}\n\n/**\n * Finds the matching strings between two arrays\n *\n * @private\n * @param {String[]} arr1 The first array\n * @param {String[]} arr2 The second array\n * @return {String[]} The shared strings between the arrays\n */\nexport function compareArrays(arr1: string[], arr2: string[]): string[] {\n return arr1.filter((e1) =>\n arr2.some((e2) => e1.toLowerCase() === e2.toLowerCase()),\n )\n}\n\ntype URIEncodable = string | number | boolean\ntype QueryValue = URIEncodable | URIEncodable[]\n\ninterface QuerystringOptions {\n arrayJoin?: string\n}\n\ninterface EncodeURIQueryValueOptions {\n arrayJoin?: string\n}\n\n/**\n * Turns an object into a query string, correctly encoding uri components\n *\n * @example\n * const options = { page: 10, limit: 100 }\n * const query = querystring(options) // 'page=10&limit=100'\n * console.log(`https://example.com?${query}`)\n *\n * @param query An object with key/value pairs that will be turned into a string\n * @returns A string that can be appended to a url (after `?`)\n */\nexport function querystring(\n query: Record<string, QueryValue>,\n { arrayJoin = '+' }: QuerystringOptions = {},\n): string {\n return Object.entries(query)\n .map(\n ([key, value]) =>\n `${encodeURIComponent(key)}=${encodeURIQueryValue(value, {\n arrayJoin,\n })}`,\n )\n .join('&')\n}\n\n/**\n * Encodes a single value or an array of values to be usable in as a URI component,\n * joining array elements with '+'\n * @param value The value to encode\n * @returns An encoded value that can be passed to a querystring\n */\nexport function encodeURIQueryValue(\n value: QueryValue,\n { arrayJoin = '+' }: EncodeURIQueryValueOptions = {},\n): string {\n if (Array.isArray(value)) {\n return value.map(encodeURIComponent).join(arrayJoin)\n }\n\n return encodeURIComponent(value)\n}\n"]}
|
package/dist/boorus/Booru.d.ts
CHANGED
|
@@ -47,7 +47,7 @@ export declare class Booru {
|
|
|
47
47
|
*
|
|
48
48
|
* @private
|
|
49
49
|
* @param site The site to use
|
|
50
|
-
* @param credentials Credentials for the API
|
|
50
|
+
* @param credentials Credentials for the API
|
|
51
51
|
*/
|
|
52
52
|
constructor(site: Site, credentials?: BooruCredentials);
|
|
53
53
|
protected normalizeTags(tags: string | string[]): string[];
|
|
@@ -58,6 +58,12 @@ export declare class Booru {
|
|
|
58
58
|
* @return {Promise<SearchResults>} The results as an array of Posts
|
|
59
59
|
*/
|
|
60
60
|
search(tags: string | string[], { limit, random, page, showUnavailable, }?: SearchParameters): Promise<SearchResults>;
|
|
61
|
+
/**
|
|
62
|
+
* Gets the total number of posts for a specific tag or tag combination
|
|
63
|
+
* @param {String|String[]} tags The tag(s) to search for
|
|
64
|
+
* @return {Promise<number>} The total number of posts
|
|
65
|
+
*/
|
|
66
|
+
getPostCount(tags: string | string[]): Promise<number>;
|
|
61
67
|
/**
|
|
62
68
|
* Gets the url you'd see in your browser from a post id for this booru
|
|
63
69
|
*
|
|
@@ -82,6 +88,16 @@ export declare class Booru {
|
|
|
82
88
|
* @return {Promise<Object>}
|
|
83
89
|
*/
|
|
84
90
|
protected doSearchRequest(tags: string[], { uri, limit, random, page, }?: InternalSearchParameters): Promise<any>;
|
|
91
|
+
/**
|
|
92
|
+
* The internal & common postCount logic, pls dont use this use .postCount instead
|
|
93
|
+
*
|
|
94
|
+
* @protected
|
|
95
|
+
* @param {String[]|String} tags The tags to search with
|
|
96
|
+
* @param {InternalSearchParameters} searchArgs The arguments for the search
|
|
97
|
+
* @return {Promise<Object>}
|
|
98
|
+
*/
|
|
99
|
+
protected doPostCountRequest(tags: string[], { uri, limit }?: InternalSearchParameters): Promise<number>;
|
|
100
|
+
private getPostCountNumber;
|
|
85
101
|
/**
|
|
86
102
|
* Generates a URL to search the booru with, mostly for debugging purposes
|
|
87
103
|
* @param opt
|
|
@@ -91,6 +107,15 @@ export declare class Booru {
|
|
|
91
107
|
* @returns A URL to search the booru
|
|
92
108
|
*/
|
|
93
109
|
getSearchUrl({ tags, limit, page, }?: Partial<SearchUrlParams>): string;
|
|
110
|
+
/**
|
|
111
|
+
* Generates a URL to search the booru with, mostly for debugging purposes
|
|
112
|
+
* @param opt
|
|
113
|
+
* @param {string[]} [opt.tags] The tags to search for
|
|
114
|
+
* @param {number} [opt.limit] The limit of results to return
|
|
115
|
+
* @param {number} [opt.page] The page of results to return
|
|
116
|
+
* @returns A URL to search the booru
|
|
117
|
+
*/
|
|
118
|
+
getPostCountUrl({ tags, limit, }?: Partial<SearchUrlParams>): string;
|
|
94
119
|
/**
|
|
95
120
|
* Generates a URL to get a list of tags from the booru
|
|
96
121
|
* @param opt
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Booru.d.ts","sourceRoot":"","sources":["../../src/boorus/Booru.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"Booru.d.ts","sourceRoot":"","sources":["../../src/boorus/Booru.ts"],"names":[],"mappings":"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"}
|
package/dist/boorus/Booru.js
CHANGED
|
@@ -53,7 +53,7 @@ class Booru {
|
|
|
53
53
|
*
|
|
54
54
|
* @private
|
|
55
55
|
* @param site The site to use
|
|
56
|
-
* @param credentials Credentials for the API
|
|
56
|
+
* @param credentials Credentials for the API
|
|
57
57
|
*/
|
|
58
58
|
constructor(site, credentials) {
|
|
59
59
|
const domain = (0, Utils_1.resolveSite)(site.domain);
|
|
@@ -102,6 +102,26 @@ class Booru {
|
|
|
102
102
|
throw err;
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* Gets the total number of posts for a specific tag or tag combination
|
|
107
|
+
* @param {String|String[]} tags The tag(s) to search for
|
|
108
|
+
* @return {Promise<number>} The total number of posts
|
|
109
|
+
*/
|
|
110
|
+
async getPostCount(tags) {
|
|
111
|
+
const tagArray = this.normalizeTags(tags);
|
|
112
|
+
try {
|
|
113
|
+
const postCountResult = await this.doPostCountRequest(tagArray, {
|
|
114
|
+
limit: 1,
|
|
115
|
+
});
|
|
116
|
+
return postCountResult;
|
|
117
|
+
}
|
|
118
|
+
catch (err) {
|
|
119
|
+
if (err instanceof Error) {
|
|
120
|
+
throw new Constants_1.BooruError(err);
|
|
121
|
+
}
|
|
122
|
+
throw err;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
105
125
|
/**
|
|
106
126
|
* Gets the url you'd see in your browser from a post id for this booru
|
|
107
127
|
*
|
|
@@ -195,11 +215,11 @@ class Booru {
|
|
|
195
215
|
}
|
|
196
216
|
}
|
|
197
217
|
const data = await response.text();
|
|
198
|
-
const posts = xml ? (0, Utils_1.jsonifyPosts)(data) : (0, Utils_1.tryParseJSON)(data);
|
|
218
|
+
const posts = xml ? (0, Utils_1.jsonifyPosts)(data).posts : (0, Utils_1.tryParseJSON)(data);
|
|
199
219
|
if (!response.ok) {
|
|
200
220
|
throw new Constants_1.BooruError(`Received HTTP ${response.status} ` +
|
|
201
|
-
`from booru: '${posts.
|
|
202
|
-
posts.
|
|
221
|
+
`from booru ${this.site.domain}: '${posts.message ??
|
|
222
|
+
posts.error ??
|
|
203
223
|
JSON.stringify(posts)}'`);
|
|
204
224
|
}
|
|
205
225
|
return posts;
|
|
@@ -210,6 +230,60 @@ class Booru {
|
|
|
210
230
|
throw err;
|
|
211
231
|
}
|
|
212
232
|
}
|
|
233
|
+
/**
|
|
234
|
+
* The internal & common postCount logic, pls dont use this use .postCount instead
|
|
235
|
+
*
|
|
236
|
+
* @protected
|
|
237
|
+
* @param {String[]|String} tags The tags to search with
|
|
238
|
+
* @param {InternalSearchParameters} searchArgs The arguments for the search
|
|
239
|
+
* @return {Promise<Object>}
|
|
240
|
+
*/
|
|
241
|
+
async doPostCountRequest(tags, { uri = null, limit = 1 } = {}) {
|
|
242
|
+
let searchTags = tags.slice();
|
|
243
|
+
if (this.site.defaultTags) {
|
|
244
|
+
searchTags = searchTags.concat(this.site.defaultTags.filter((v) => !searchTags.includes(v)));
|
|
245
|
+
}
|
|
246
|
+
const fetchuri = uri ?? this.getPostCountUrl({ tags: searchTags, limit });
|
|
247
|
+
try {
|
|
248
|
+
const response = await resolvedFetch(fetchuri, Constants_1.defaultOptions);
|
|
249
|
+
// Check for CloudFlare ratelimiting
|
|
250
|
+
if (response.status === 503) {
|
|
251
|
+
const body = await response.clone().text();
|
|
252
|
+
if (body.includes('cf-browser-verification')) {
|
|
253
|
+
throw new Constants_1.BooruError("Received a CloudFlare browser verification request. Can't proceed.");
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
const data = await response.text();
|
|
257
|
+
if (!response.ok) {
|
|
258
|
+
throw new Constants_1.BooruError(`Received HTTP ${response.status} ` +
|
|
259
|
+
`from booru: '${data.error ??
|
|
260
|
+
data.message ??
|
|
261
|
+
JSON.stringify(data)}'`);
|
|
262
|
+
}
|
|
263
|
+
const postCountType = this.site.postCountType;
|
|
264
|
+
return this.getPostCountNumber(postCountType, data);
|
|
265
|
+
}
|
|
266
|
+
catch (err) {
|
|
267
|
+
if (err.type === 'invalid-json')
|
|
268
|
+
return 0;
|
|
269
|
+
throw err;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
getPostCountNumber(postCountType, data) {
|
|
273
|
+
if (postCountType === 'json') {
|
|
274
|
+
return (0, Utils_1.tryParseJSON)(data).counts.posts;
|
|
275
|
+
}
|
|
276
|
+
if (postCountType === 'derpi') {
|
|
277
|
+
return (0, Utils_1.tryParseJSON)(data).total;
|
|
278
|
+
}
|
|
279
|
+
if (postCountType === 'xml') {
|
|
280
|
+
const jsonData = (0, Utils_1.jsonifyPosts)(data);
|
|
281
|
+
if (jsonData.count !== undefined) {
|
|
282
|
+
return jsonData.count;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
return -1;
|
|
286
|
+
}
|
|
213
287
|
/**
|
|
214
288
|
* Generates a URL to search the booru with, mostly for debugging purposes
|
|
215
289
|
* @param opt
|
|
@@ -221,6 +295,17 @@ class Booru {
|
|
|
221
295
|
getSearchUrl({ tags = [], limit = 100, page = 1, } = {}) {
|
|
222
296
|
return (0, Constants_1.searchURI)(this.site, tags, limit, page, this.credentials);
|
|
223
297
|
}
|
|
298
|
+
/**
|
|
299
|
+
* Generates a URL to search the booru with, mostly for debugging purposes
|
|
300
|
+
* @param opt
|
|
301
|
+
* @param {string[]} [opt.tags] The tags to search for
|
|
302
|
+
* @param {number} [opt.limit] The limit of results to return
|
|
303
|
+
* @param {number} [opt.page] The page of results to return
|
|
304
|
+
* @returns A URL to search the booru
|
|
305
|
+
*/
|
|
306
|
+
getPostCountUrl({ tags = [], limit = 1, } = {}) {
|
|
307
|
+
return (0, Constants_1.postCountURI)(this.site, tags, limit, this.credentials);
|
|
308
|
+
}
|
|
224
309
|
/**
|
|
225
310
|
* Generates a URL to get a list of tags from the booru
|
|
226
311
|
* @param opt
|
package/dist/boorus/Booru.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Booru.js","sourceRoot":"","sources":["../../src/boorus/Booru.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @packageDocumentation\n * @module Boorus\n */\n\nimport { fetch } from 'undici'\nimport { BooruError, defaultOptions, searchURI, tagListURI } from '../Constants'\nimport type InternalSearchParameters from '../structures/InternalSearchParameters'\nimport Post from '../structures/Post'\nimport type SearchParameters from '../structures/SearchParameters'\nimport SearchResults from '../structures/SearchResults'\nimport type Site from '../structures/Site'\nimport Tag from '../structures/Tag'\nimport TagListResults from '../structures/TagListResults'\nimport {\n jsonifyPosts,\n jsonifyTags,\n resolveSite,\n shuffle,\n tryParseJSON,\n} from '../Utils'\n\n// Shut up the compiler\n// This attempts to find and use the native browser fetch, if possible\n// Fixes https://github.com/AtoraSuunva/booru/issues/51\ndeclare const window: any\nconst resolvedFetch: typeof fetch =\n typeof window !== 'undefined' ? window.fetch.bind(window) : fetch\n\nexport type BooruCredentials = Record<string, string>\n\ninterface SearchUrlParams {\n tags: string[]\n limit: number\n page: number\n}\n\ninterface TagsURLParams {\n limit?: number | undefined\n page?: number | undefined\n}\n\n/*\n - new Booru\n => Constructor, params {name, {nsfw, {search, postView, ...}, random}, {apiTokens...}}\n => .search([tags...], {limit, random})\n => .postView(id)\n => .site\n */\n\n/**\n * A basic, JSON booru\n * @example\n * ```\n * const Booru = require('booru')\n * // Aliases are supported\n * const e9 = Booru('e9')\n *\n * // You can then search the site\n * const imgs = await e9.search(['cat', 'cute'], {limit: 3})\n *\n * // And use the images\n * imgs.forEach(i => console.log(i.fileUrl))\n *\n * // Or access other methods on the Booru\n * e9.postView(imgs[0].id)\n * ```\n */\nexport class Booru {\n /** The domain of the booru */\n public domain: string\n /** The site object representing this booru */\n public site: Site\n /** The credentials to use for this booru */\n public credentials?: BooruCredentials | undefined\n\n /**\n * Create a new booru from a site\n *\n * @private\n * @param site The site to use\n * @param credentials Credentials for the API (Currently not used)\n */\n constructor(site: Site, credentials?: BooruCredentials) {\n const domain = resolveSite(site.domain)\n\n if (domain === null) {\n throw new Error(`Invalid site passed: ${site.domain}`)\n }\n\n this.domain = domain\n this.site = site\n this.credentials = credentials\n }\n\n protected normalizeTags(tags: string | string[]): string[] {\n if (!Array.isArray(tags)) {\n return [tags]\n }\n\n return tags.slice()\n }\n\n /**\n * Search for images on this booru\n * @param {String|String[]} tags The tag(s) to search for\n * @param {SearchParameters} searchArgs The arguments for the search\n * @return {Promise<SearchResults>} The results as an array of Posts\n */\n public async search(\n tags: string | string[],\n {\n limit = 1,\n random = false,\n page = 0,\n showUnavailable = false,\n }: SearchParameters = {},\n ): Promise<SearchResults> {\n const fakeLimit: number = random && !this.site.random ? 100 : 0\n const tagArray = this.normalizeTags(tags)\n\n try {\n const searchResult = await this.doSearchRequest(tagArray, {\n limit,\n random,\n page,\n showUnavailable,\n })\n return this.parseSearchResult(searchResult, {\n fakeLimit,\n tags: tagArray,\n limit,\n random,\n page,\n showUnavailable,\n })\n } catch (err) {\n if (err instanceof Error) {\n throw new BooruError(err)\n }\n\n throw err\n }\n }\n\n /**\n * Gets the url you'd see in your browser from a post id for this booru\n *\n * @param {String} id The id to get the postView for\n * @return {String} The url to the post\n */\n public postView(id: string | number): string {\n if (typeof id === 'string' && Number.isNaN(Number.parseInt(id, 10))) {\n throw new BooruError(`Not a valid id for postView: ${id}`)\n }\n\n return `http${this.site.insecure ? '' : 's'}://${this.domain}${\n this.site.api.postView\n }${id}`\n }\n\n /**\n * Gets a list of tags from the booru\n * @param {Partial<TagsURLParams>} [params] The parameters for the tags list\n * @param {number} [params.limit=100] The limit of tags to return\n * @param {number} [params.page=1] The page of tags to return\n * @return {Promise<any[]>} A promise with the tags as an array\n */\n public async tagList({\n limit = 100,\n page = 1,\n }: Partial<TagsURLParams> = {}): Promise<TagListResults> {\n const url = this.getTagListUrl({ limit, page })\n const options = defaultOptions\n try {\n const response = await resolvedFetch(url, options)\n\n // Check for CloudFlare ratelimiting\n if (response.status === 503) {\n const body = await response.clone().text()\n if (body.includes('cf-browser-verification')) {\n throw new BooruError(\n \"Received a CloudFlare browser verification request. Can't proceed.\",\n )\n }\n }\n\n if (!response.ok) {\n throw new BooruError(\n `Received HTTP ${response.status} from booru: '${await response.text()}'`,\n )\n }\n\n const data = await response.text()\n /**\n * Many boorus don't support JSON parameter for tag listing\n * So attempt JSON parsing, but if it fails default to XML parsing\n **/\n let tags = []\n try {\n tags = tryParseJSON(data)\n } catch (_e) {\n tags = jsonifyTags(data)\n }\n\n return this.parseTagListResult(tags, { limit, page })\n } catch (err) {\n if ((err as any).type === 'invalid-json')\n if (err instanceof Error) {\n throw new BooruError(err)\n }\n\n throw err\n }\n }\n\n /**\n * The internal & common searching logic, pls dont use this use .search instead\n *\n * @protected\n * @param {String[]|String} tags The tags to search with\n * @param {InternalSearchParameters} searchArgs The arguments for the search\n * @return {Promise<Object>}\n */\n protected async doSearchRequest(\n tags: string[],\n {\n uri = null,\n limit = 1,\n random = false,\n page = 0,\n }: InternalSearchParameters = {},\n ): Promise<any> {\n // Used for random on sites without order:random\n let fakeLimit: number | undefined\n let searchTags = tags.slice()\n\n if (random) {\n if (this.site.random) {\n searchTags.push('order:random')\n } else {\n fakeLimit = 100\n }\n }\n\n if (this.site.defaultTags) {\n searchTags = searchTags.concat(\n this.site.defaultTags.filter((v) => !searchTags.includes(v)),\n )\n }\n\n const fetchuri =\n uri ??\n this.getSearchUrl({ tags: searchTags, limit: fakeLimit ?? limit, page })\n const options = defaultOptions\n const xml = this.site.type === 'xml'\n\n try {\n const response = await resolvedFetch(fetchuri, options)\n\n // Check for CloudFlare ratelimiting\n if (response.status === 503) {\n const body = await response.clone().text()\n if (body.includes('cf-browser-verification')) {\n throw new BooruError(\n \"Received a CloudFlare browser verification request. Can't proceed.\",\n )\n }\n }\n\n const data = await response.text()\n const posts = xml ? jsonifyPosts(data) : tryParseJSON(data)\n\n if (!response.ok) {\n throw new BooruError(\n `Received HTTP ${response.status} ` +\n `from booru: '${\n (posts as any).error ??\n (posts as any).message ??\n JSON.stringify(posts)\n }'`,\n )\n }\n\n return posts\n } catch (err) {\n if ((err as any).type === 'invalid-json') return ''\n throw err\n }\n }\n\n /**\n * Generates a URL to search the booru with, mostly for debugging purposes\n * @param opt\n * @param {string[]} [opt.tags] The tags to search for\n * @param {number} [opt.limit] The limit of results to return\n * @param {number} [opt.page] The page of results to return\n * @returns A URL to search the booru\n */\n getSearchUrl({\n tags = [],\n limit = 100,\n page = 1,\n }: Partial<SearchUrlParams> = {}): string {\n return searchURI(this.site, tags, limit, page, this.credentials)\n }\n\n /**\n * Generates a URL to get a list of tags from the booru\n * @param opt\n * @param {number} [opt.limit] The limit of tags to return\n * @param {number} [opt.page] The page of tags to return\n * @returns {string} A URL to get the tags list\n */\n getTagListUrl({\n limit = 100,\n page = 1,\n }: Partial<TagsURLParams> = {}): string {\n if (!this.site.api.tagList) {\n throw new BooruError(\n `This booru does not support tag listing: ${this.site.domain}`,\n )\n }\n return tagListURI(this.site, limit, page, this.credentials)\n }\n\n /**\n * Parse the response from the booru\n *\n * @protected\n * @param {Object} result The response of the booru\n * @param {InternalSearchParameters} searchArgs The arguments used for the search\n * @return {SearchResults} The results of this search\n */\n protected parseSearchResult(\n result: any,\n {\n fakeLimit,\n tags,\n limit,\n random,\n page,\n showUnavailable,\n }: InternalSearchParameters,\n ): SearchResults {\n let outResult = result\n\n if (outResult.success === false) {\n throw new BooruError(outResult.message ?? outResult.reason)\n }\n\n // Gelbooru\n if (outResult['@attributes']) {\n const attributes = outResult['@attributes']\n\n if (attributes.count === '0' || !outResult.post) {\n outResult = []\n } else if (Array.isArray(outResult.post)) {\n outResult = outResult.post\n } else {\n outResult = [outResult.post]\n }\n }\n\n if (outResult.posts) {\n outResult = outResult.posts\n }\n\n if (outResult.images) {\n outResult = outResult.images\n }\n\n let r: string[] | undefined\n // If gelbooru/other booru decides to return *nothing* instead of an empty array\n if (outResult === '') {\n r = []\n } else if (fakeLimit) {\n r = shuffle(outResult)\n } else if (outResult.constructor === Object) {\n // For XML based sites\n r = [outResult]\n }\n\n let posts: Post[] = (r ?? outResult)\n .slice(0, limit)\n .map((v: any) => new Post(v, this))\n const options = { limit, random, page, showUnavailable }\n\n if (tags === undefined) {\n tags = []\n }\n\n if (!showUnavailable) {\n posts = posts.filter((p) => p.available)\n }\n\n return new SearchResults(posts, tags, options, this)\n }\n\n /**\n * Parse the response from the booru for a tag list\n *\n * @param result\n * @param param1\n * @returns\n */\n protected parseTagListResult(\n result: any,\n { limit = 100, page = 1 }: Partial<TagsURLParams> = {},\n ): TagListResults {\n if (result.success === false) {\n throw new BooruError(result.message ?? result.reason)\n }\n\n let tags: any[] = []\n\n if (result) {\n if (Array.isArray(result)) {\n tags = result.map((v) => new Tag(v, this))\n } else {\n tags = [new Tag(result, this)]\n }\n }\n\n return new TagListResults(tags, { limit, page }, this)\n }\n}\n\nexport default Booru\n"]}
|
|
1
|
+
{"version":3,"file":"Booru.js","sourceRoot":"","sources":["../../src/boorus/Booru.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @packageDocumentation\n * @module Boorus\n */\n\nimport { fetch } from 'undici'\nimport {\n BooruError,\n defaultOptions,\n postCountURI,\n searchURI,\n tagListURI,\n} from '../Constants'\nimport type InternalSearchParameters from '../structures/InternalSearchParameters'\nimport Post from '../structures/Post'\nimport type SearchParameters from '../structures/SearchParameters'\nimport SearchResults from '../structures/SearchResults'\nimport type Site from '../structures/Site'\nimport Tag from '../structures/Tag'\nimport TagListResults from '../structures/TagListResults'\nimport {\n jsonifyPosts,\n jsonifyTags,\n resolveSite,\n shuffle,\n tryParseJSON,\n} from '../Utils'\n\n// Shut up the compiler\n// This attempts to find and use the native browser fetch, if possible\n// Fixes https://github.com/AtoraSuunva/booru/issues/51\ndeclare const window: any\nconst resolvedFetch: typeof fetch =\n typeof window !== 'undefined' ? window.fetch.bind(window) : fetch\n\nexport type BooruCredentials = Record<string, string>\n\ninterface SearchUrlParams {\n tags: string[]\n limit: number\n page: number\n}\n\ninterface TagsURLParams {\n limit?: number | undefined\n page?: number | undefined\n}\n\n/*\n - new Booru\n => Constructor, params {name, {nsfw, {search, postView, ...}, random}, {apiTokens...}}\n => .search([tags...], {limit, random})\n => .postView(id)\n => .site\n */\n\n/**\n * A basic, JSON booru\n * @example\n * ```\n * const Booru = require('booru')\n * // Aliases are supported\n * const e9 = Booru('e9')\n *\n * // You can then search the site\n * const imgs = await e9.search(['cat', 'cute'], {limit: 3})\n *\n * // And use the images\n * imgs.forEach(i => console.log(i.fileUrl))\n *\n * // Or access other methods on the Booru\n * e9.postView(imgs[0].id)\n * ```\n */\nexport class Booru {\n /** The domain of the booru */\n public domain: string\n /** The site object representing this booru */\n public site: Site\n /** The credentials to use for this booru */\n public credentials?: BooruCredentials | undefined\n\n /**\n * Create a new booru from a site\n *\n * @private\n * @param site The site to use\n * @param credentials Credentials for the API\n */\n constructor(site: Site, credentials?: BooruCredentials) {\n const domain = resolveSite(site.domain)\n\n if (domain === null) {\n throw new Error(`Invalid site passed: ${site.domain}`)\n }\n\n this.domain = domain\n this.site = site\n this.credentials = credentials\n }\n\n protected normalizeTags(tags: string | string[]): string[] {\n if (!Array.isArray(tags)) {\n return [tags]\n }\n\n return tags.slice()\n }\n\n /**\n * Search for images on this booru\n * @param {String|String[]} tags The tag(s) to search for\n * @param {SearchParameters} searchArgs The arguments for the search\n * @return {Promise<SearchResults>} The results as an array of Posts\n */\n public async search(\n tags: string | string[],\n {\n limit = 1,\n random = false,\n page = 0,\n showUnavailable = false,\n }: SearchParameters = {},\n ): Promise<SearchResults> {\n const fakeLimit: number = random && !this.site.random ? 100 : 0\n const tagArray = this.normalizeTags(tags)\n\n try {\n const searchResult = await this.doSearchRequest(tagArray, {\n limit,\n random,\n page,\n showUnavailable,\n })\n return this.parseSearchResult(searchResult, {\n fakeLimit,\n tags: tagArray,\n limit,\n random,\n page,\n showUnavailable,\n })\n } catch (err) {\n if (err instanceof Error) {\n throw new BooruError(err)\n }\n\n throw err\n }\n }\n\n /**\n * Gets the total number of posts for a specific tag or tag combination\n * @param {String|String[]} tags The tag(s) to search for\n * @return {Promise<number>} The total number of posts\n */\n public async getPostCount(tags: string | string[]): Promise<number> {\n const tagArray = this.normalizeTags(tags)\n\n try {\n const postCountResult = await this.doPostCountRequest(tagArray, {\n limit: 1,\n })\n\n return postCountResult\n } catch (err) {\n if (err instanceof Error) {\n throw new BooruError(err)\n }\n\n throw err\n }\n }\n\n /**\n * Gets the url you'd see in your browser from a post id for this booru\n *\n * @param {String} id The id to get the postView for\n * @return {String} The url to the post\n */\n public postView(id: string | number): string {\n if (typeof id === 'string' && Number.isNaN(Number.parseInt(id, 10))) {\n throw new BooruError(`Not a valid id for postView: ${id}`)\n }\n\n return `http${this.site.insecure ? '' : 's'}://${this.domain}${\n this.site.api.postView\n }${id}`\n }\n\n /**\n * Gets a list of tags from the booru\n * @param {Partial<TagsURLParams>} [params] The parameters for the tags list\n * @param {number} [params.limit=100] The limit of tags to return\n * @param {number} [params.page=1] The page of tags to return\n * @return {Promise<any[]>} A promise with the tags as an array\n */\n public async tagList({\n limit = 100,\n page = 1,\n }: Partial<TagsURLParams> = {}): Promise<TagListResults> {\n const url = this.getTagListUrl({ limit, page })\n const options = defaultOptions\n try {\n const response = await resolvedFetch(url, options)\n\n // Check for CloudFlare ratelimiting\n if (response.status === 503) {\n const body = await response.clone().text()\n if (body.includes('cf-browser-verification')) {\n throw new BooruError(\n \"Received a CloudFlare browser verification request. Can't proceed.\",\n )\n }\n }\n\n if (!response.ok) {\n throw new BooruError(\n `Received HTTP ${response.status} from booru: '${await response.text()}'`,\n )\n }\n\n const data = await response.text()\n /**\n * Many boorus don't support JSON parameter for tag listing\n * So attempt JSON parsing, but if it fails default to XML parsing\n **/\n let tags = []\n try {\n tags = tryParseJSON(data)\n } catch (_e) {\n tags = jsonifyTags(data)\n }\n\n return this.parseTagListResult(tags, { limit, page })\n } catch (err) {\n if ((err as any).type === 'invalid-json')\n if (err instanceof Error) {\n throw new BooruError(err)\n }\n\n throw err\n }\n }\n\n /**\n * The internal & common searching logic, pls dont use this use .search instead\n *\n * @protected\n * @param {String[]|String} tags The tags to search with\n * @param {InternalSearchParameters} searchArgs The arguments for the search\n * @return {Promise<Object>}\n */\n protected async doSearchRequest(\n tags: string[],\n {\n uri = null,\n limit = 1,\n random = false,\n page = 0,\n }: InternalSearchParameters = {},\n ): Promise<any> {\n // Used for random on sites without order:random\n let fakeLimit: number | undefined\n let searchTags = tags.slice()\n\n if (random) {\n if (this.site.random) {\n searchTags.push('order:random')\n } else {\n fakeLimit = 100\n }\n }\n\n if (this.site.defaultTags) {\n searchTags = searchTags.concat(\n this.site.defaultTags.filter((v) => !searchTags.includes(v)),\n )\n }\n\n const fetchuri =\n uri ??\n this.getSearchUrl({ tags: searchTags, limit: fakeLimit ?? limit, page })\n\n const options = defaultOptions\n const xml = this.site.type === 'xml'\n\n try {\n const response = await resolvedFetch(fetchuri, options)\n\n // Check for CloudFlare ratelimiting\n if (response.status === 503) {\n const body = await response.clone().text()\n if (body.includes('cf-browser-verification')) {\n throw new BooruError(\n \"Received a CloudFlare browser verification request. Can't proceed.\",\n )\n }\n }\n\n const data = await response.text()\n const posts = xml ? jsonifyPosts(data).posts : tryParseJSON(data)\n\n if (!response.ok) {\n throw new BooruError(\n `Received HTTP ${response.status} ` +\n `from booru ${this.site.domain}: '${\n (posts as any).message ??\n (posts as any).error ??\n JSON.stringify(posts)\n }'`,\n )\n }\n\n return posts\n } catch (err) {\n if ((err as any).type === 'invalid-json') return ''\n throw err\n }\n }\n\n /**\n * The internal & common postCount logic, pls dont use this use .postCount instead\n *\n * @protected\n * @param {String[]|String} tags The tags to search with\n * @param {InternalSearchParameters} searchArgs The arguments for the search\n * @return {Promise<Object>}\n */\n protected async doPostCountRequest(\n tags: string[],\n { uri = null, limit = 1 }: InternalSearchParameters = {},\n ): Promise<number> {\n let searchTags = tags.slice()\n\n if (this.site.defaultTags) {\n searchTags = searchTags.concat(\n this.site.defaultTags.filter((v) => !searchTags.includes(v)),\n )\n }\n\n const fetchuri = uri ?? this.getPostCountUrl({ tags: searchTags, limit })\n\n try {\n const response = await resolvedFetch(fetchuri, defaultOptions)\n\n // Check for CloudFlare ratelimiting\n if (response.status === 503) {\n const body = await response.clone().text()\n if (body.includes('cf-browser-verification')) {\n throw new BooruError(\n \"Received a CloudFlare browser verification request. Can't proceed.\",\n )\n }\n }\n\n const data = await response.text()\n\n if (!response.ok) {\n throw new BooruError(\n `Received HTTP ${response.status} ` +\n `from booru: '${\n (data as any).error ??\n (data as any).message ??\n JSON.stringify(data)\n }'`,\n )\n }\n\n const postCountType = this.site.postCountType\n\n return this.getPostCountNumber(postCountType, data)\n } catch (err) {\n if ((err as any).type === 'invalid-json') return 0\n throw err\n }\n }\n\n private getPostCountNumber(\n postCountType: 'json' | 'xml' | 'derpi',\n data: string,\n ) {\n if (postCountType === 'json') {\n return (tryParseJSON(data) as any).counts.posts\n }\n if (postCountType === 'derpi') {\n return (tryParseJSON(data) as any).total\n }\n if (postCountType === 'xml') {\n const jsonData = jsonifyPosts(data)\n if (jsonData.count !== undefined) {\n return jsonData.count\n }\n }\n return -1\n }\n\n /**\n * Generates a URL to search the booru with, mostly for debugging purposes\n * @param opt\n * @param {string[]} [opt.tags] The tags to search for\n * @param {number} [opt.limit] The limit of results to return\n * @param {number} [opt.page] The page of results to return\n * @returns A URL to search the booru\n */\n getSearchUrl({\n tags = [],\n limit = 100,\n page = 1,\n }: Partial<SearchUrlParams> = {}): string {\n return searchURI(this.site, tags, limit, page, this.credentials)\n }\n\n /**\n * Generates a URL to search the booru with, mostly for debugging purposes\n * @param opt\n * @param {string[]} [opt.tags] The tags to search for\n * @param {number} [opt.limit] The limit of results to return\n * @param {number} [opt.page] The page of results to return\n * @returns A URL to search the booru\n */\n getPostCountUrl({\n tags = [],\n limit = 1,\n }: Partial<SearchUrlParams> = {}): string {\n return postCountURI(this.site, tags, limit, this.credentials)\n }\n\n /**\n * Generates a URL to get a list of tags from the booru\n * @param opt\n * @param {number} [opt.limit] The limit of tags to return\n * @param {number} [opt.page] The page of tags to return\n * @returns {string} A URL to get the tags list\n */\n getTagListUrl({\n limit = 100,\n page = 1,\n }: Partial<TagsURLParams> = {}): string {\n if (!this.site.api.tagList) {\n throw new BooruError(\n `This booru does not support tag listing: ${this.site.domain}`,\n )\n }\n return tagListURI(this.site, limit, page, this.credentials)\n }\n\n /**\n * Parse the response from the booru\n *\n * @protected\n * @param {Object} result The response of the booru\n * @param {InternalSearchParameters} searchArgs The arguments used for the search\n * @return {SearchResults} The results of this search\n */\n protected parseSearchResult(\n result: any,\n {\n fakeLimit,\n tags,\n limit,\n random,\n page,\n showUnavailable,\n }: InternalSearchParameters,\n ): SearchResults {\n let outResult = result\n\n if (outResult.success === false) {\n throw new BooruError(outResult.message ?? outResult.reason)\n }\n\n // Gelbooru\n if (outResult['@attributes']) {\n const attributes = outResult['@attributes']\n\n if (attributes.count === '0' || !outResult.post) {\n outResult = []\n } else if (Array.isArray(outResult.post)) {\n outResult = outResult.post\n } else {\n outResult = [outResult.post]\n }\n }\n\n if (outResult.posts) {\n outResult = outResult.posts\n }\n\n if (outResult.images) {\n outResult = outResult.images\n }\n\n let r: string[] | undefined\n // If gelbooru/other booru decides to return *nothing* instead of an empty array\n if (outResult === '') {\n r = []\n } else if (fakeLimit) {\n r = shuffle(outResult)\n } else if (outResult.constructor === Object) {\n // For XML based sites\n r = [outResult]\n }\n\n let posts: Post[] = (r ?? outResult)\n .slice(0, limit)\n .map((v: any) => new Post(v, this))\n const options = { limit, random, page, showUnavailable }\n\n if (tags === undefined) {\n tags = []\n }\n\n if (!showUnavailable) {\n posts = posts.filter((p) => p.available)\n }\n\n return new SearchResults(posts, tags, options, this)\n }\n\n /**\n * Parse the response from the booru for a tag list\n *\n * @param result\n * @param param1\n * @returns\n */\n protected parseTagListResult(\n result: any,\n { limit = 100, page = 1 }: Partial<TagsURLParams> = {},\n ): TagListResults {\n if (result.success === false) {\n throw new BooruError(result.message ?? result.reason)\n }\n\n let tags: any[] = []\n\n if (result) {\n if (Array.isArray(result)) {\n tags = result.map((v) => new Tag(v, this))\n } else {\n tags = [new Tag(result, this)]\n }\n }\n\n return new TagListResults(tags, { limit, page }, this)\n }\n}\n\nexport default Booru\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -25,6 +25,9 @@ export default booruForSite;
|
|
|
25
25
|
export interface BooruSearch extends SearchParameters {
|
|
26
26
|
credentials?: BooruCredentials;
|
|
27
27
|
}
|
|
28
|
+
export interface BooruPostCountOptions {
|
|
29
|
+
credentials?: BooruCredentials;
|
|
30
|
+
}
|
|
28
31
|
export interface BooruTagList extends TagListParameters {
|
|
29
32
|
credentials?: BooruCredentials;
|
|
30
33
|
}
|
|
@@ -44,6 +47,21 @@ export interface BooruTagList extends TagListParameters {
|
|
|
44
47
|
* ```
|
|
45
48
|
*/
|
|
46
49
|
export declare function search(site: string, tags?: string[] | string, { limit, random, page, credentials }?: BooruSearch): Promise<SearchResults>;
|
|
50
|
+
/**
|
|
51
|
+
* Gets the total number of posts for specific tags
|
|
52
|
+
* @param {String} site The site to search
|
|
53
|
+
* @param {String[]|String} [tags=[]] Tags to check the count for
|
|
54
|
+
* @param {BooruPostCountOptions} [options={}] The options (credentials)
|
|
55
|
+
* @return {Promise<number>} A promise with the total number of posts
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```
|
|
59
|
+
* const Booru = require('booru')
|
|
60
|
+
* // Returns the total amount of posts for 'cat' on e926
|
|
61
|
+
* const count = await Booru.postCount('e926', ['cat'])
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
export declare function postCount(site: string, tags?: string[] | string, { credentials }?: BooruPostCountOptions): Promise<number>;
|
|
47
65
|
/**
|
|
48
66
|
* Get a list of tags from a site
|
|
49
67
|
* @param {String} site The site to get the tags from
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,EAAE,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAC7D,OAAO,UAAU,MAAM,qBAAqB,CAAA;AAC5C,OAAO,QAAQ,MAAM,mBAAmB,CAAA;AAExC,OAAO,IAAI,MAAM,mBAAmB,CAAA;AACpC,OAAO,KAAK,gBAAgB,MAAM,+BAA+B,CAAA;AACjE,OAAO,aAAa,MAAM,4BAA4B,CAAA;AACtD,OAAO,IAAI,MAAM,mBAAmB,CAAA;AACpC,OAAO,KAAK,iBAAiB,MAAM,gCAAgC,CAAA;AACnE,OAAO,KAAK,cAAc,MAAM,6BAA6B,CAAA;AAyB7D;;;;;;;GAOG;AACH,iBAAS,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,gBAAgB,GAAG,KAAK,CASzE;AAED,OAAO,EAAE,YAAY,IAAI,OAAO,EAAE,CAAA;AAClC,eAAe,YAAY,CAAA;AAE3B,MAAM,WAAW,WAAY,SAAQ,gBAAgB;IACnD,WAAW,CAAC,EAAE,gBAAgB,CAAA;CAC/B;AAED,MAAM,WAAW,YAAa,SAAQ,iBAAiB;IACrD,WAAW,CAAC,EAAE,gBAAgB,CAAA;CAC/B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,MAAM,CACpB,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,MAAM,EAAE,GAAG,MAAW,EAC5B,EAAE,KAAS,EAAE,MAAc,EAAE,IAAQ,EAAE,WAAgB,EAAE,GAAE,WAAgB,GAC1E,OAAO,CAAC,aAAa,CAAC,CA4BxB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,OAAO,CACrB,IAAI,EAAE,MAAM,EACZ,EAAE,KAAS,EAAE,IAAQ,EAAE,WAAgB,EAAE,GAAE,YAAiB,GAC3D,OAAO,CAAC,cAAc,CAAC,CAezB;AAOD;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAGxD;AAED,OAAO,EAAE,KAAK,IAAI,UAAU,EAAE,MAAM,gBAAgB,CAAA;AACpD,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AACrC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAA;AAC1D,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,EAAE,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAC7D,OAAO,UAAU,MAAM,qBAAqB,CAAA;AAC5C,OAAO,QAAQ,MAAM,mBAAmB,CAAA;AAExC,OAAO,IAAI,MAAM,mBAAmB,CAAA;AACpC,OAAO,KAAK,gBAAgB,MAAM,+BAA+B,CAAA;AACjE,OAAO,aAAa,MAAM,4BAA4B,CAAA;AACtD,OAAO,IAAI,MAAM,mBAAmB,CAAA;AACpC,OAAO,KAAK,iBAAiB,MAAM,gCAAgC,CAAA;AACnE,OAAO,KAAK,cAAc,MAAM,6BAA6B,CAAA;AAyB7D;;;;;;;GAOG;AACH,iBAAS,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,gBAAgB,GAAG,KAAK,CASzE;AAED,OAAO,EAAE,YAAY,IAAI,OAAO,EAAE,CAAA;AAClC,eAAe,YAAY,CAAA;AAE3B,MAAM,WAAW,WAAY,SAAQ,gBAAgB;IACnD,WAAW,CAAC,EAAE,gBAAgB,CAAA;CAC/B;AAED,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,EAAE,gBAAgB,CAAA;CAC/B;AAED,MAAM,WAAW,YAAa,SAAQ,iBAAiB;IACrD,WAAW,CAAC,EAAE,gBAAgB,CAAA;CAC/B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,MAAM,CACpB,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,MAAM,EAAE,GAAG,MAAW,EAC5B,EAAE,KAAS,EAAE,MAAc,EAAE,IAAQ,EAAE,WAAgB,EAAE,GAAE,WAAgB,GAC1E,OAAO,CAAC,aAAa,CAAC,CA4BxB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,MAAM,EAAE,GAAG,MAAW,EAC5B,EAAE,WAAgB,EAAE,GAAE,qBAA0B,GAC/C,OAAO,CAAC,MAAM,CAAC,CAoBjB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,OAAO,CACrB,IAAI,EAAE,MAAM,EACZ,EAAE,KAAS,EAAE,IAAQ,EAAE,WAAgB,EAAE,GAAE,YAAiB,GAC3D,OAAO,CAAC,cAAc,CAAC,CAezB;AAOD;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAGxD;AAED,OAAO,EAAE,KAAK,IAAI,UAAU,EAAE,MAAM,gBAAgB,CAAA;AACpD,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AACrC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAA;AAC1D,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -10,6 +10,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
10
10
|
exports.XmlBooru = exports.Site = exports.SearchResults = exports.Post = exports.Derpibooru = exports.resolveSite = exports.sites = exports.BooruError = exports.BooruClass = void 0;
|
|
11
11
|
exports.forSite = booruForSite;
|
|
12
12
|
exports.search = search;
|
|
13
|
+
exports.postCount = postCount;
|
|
13
14
|
exports.tagList = tagList;
|
|
14
15
|
exports.commonfy = commonfy;
|
|
15
16
|
const node_util_1 = require("node:util");
|
|
@@ -97,6 +98,35 @@ function search(site, tags = [], { limit = 1, random = false, page = 0, credenti
|
|
|
97
98
|
booruCache[rSite].credentials = credentials;
|
|
98
99
|
return booruCache[rSite].search(tags, { limit, random, page });
|
|
99
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* Gets the total number of posts for specific tags
|
|
103
|
+
* @param {String} site The site to search
|
|
104
|
+
* @param {String[]|String} [tags=[]] Tags to check the count for
|
|
105
|
+
* @param {BooruPostCountOptions} [options={}] The options (credentials)
|
|
106
|
+
* @return {Promise<number>} A promise with the total number of posts
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```
|
|
110
|
+
* const Booru = require('booru')
|
|
111
|
+
* // Returns the total amount of posts for 'cat' on e926
|
|
112
|
+
* const count = await Booru.postCount('e926', ['cat'])
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
function postCount(site, tags = [], { credentials = {} } = {}) {
|
|
116
|
+
const rSite = (0, Utils_1.resolveSite)(site);
|
|
117
|
+
if (rSite === null) {
|
|
118
|
+
throw new Constants_1.BooruError('Site not supported');
|
|
119
|
+
}
|
|
120
|
+
if (!Array.isArray(tags) && typeof tags !== 'string') {
|
|
121
|
+
throw new Constants_1.BooruError('`tags` should be an array or string');
|
|
122
|
+
}
|
|
123
|
+
const booruSite = new Site_1.default(Constants_1.sites[rSite]);
|
|
124
|
+
if (!booruCache[rSite]) {
|
|
125
|
+
booruCache[rSite] = booruFrom(booruSite, credentials);
|
|
126
|
+
}
|
|
127
|
+
booruCache[rSite].credentials = credentials;
|
|
128
|
+
return booruCache[rSite]?.getPostCount(tags);
|
|
129
|
+
}
|
|
100
130
|
/**
|
|
101
131
|
* Get a list of tags from a site
|
|
102
132
|
* @param {String} site The site to get the tags from
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @packageDocumentation\n * @module Index\n */\n\nimport { deprecate } from 'node:util'\nimport Booru, { type BooruCredentials } from './boorus/Booru'\nimport Derpibooru from './boorus/Derpibooru'\nimport XmlBooru from './boorus/XmlBooru'\nimport { type AnySite, BooruError, sites } from './Constants'\nimport Post from './structures/Post'\nimport type SearchParameters from './structures/SearchParameters'\nimport SearchResults from './structures/SearchResults'\nimport Site from './structures/Site'\nimport type TagListParameters from './structures/TagListParameters'\nimport type TagListResults from './structures/TagListResults'\nimport { resolveSite } from './Utils'\n\nconst BooruTypes: Record<string, typeof Booru> = {\n derpi: Derpibooru,\n xml: XmlBooru,\n}\n\nconst booruCache: Partial<Record<AnySite, Booru>> = {}\n\n/**\n * Create a new booru, if special type, use that booru, else use default Booru\n *\n * @param booruSite The site to use\n * @param credentials The credentials to use, if any\n * @return A new booru\n */\nfunction booruFrom(booruSite: Site, credentials?: BooruCredentials): Booru {\n return new (\n booruSite.type !== undefined && BooruTypes[booruSite.type]\n ? BooruTypes[booruSite.type]\n : Booru\n )(booruSite, credentials)\n}\n\n/**\n * Create a new booru to search with\n *\n * @constructor\n * @param {String} site The {@link Site} domain (or alias of it) to create a booru from\n * @param {BooruCredentials} credentials The credentials to use on this booru\n * @return {Booru} A booru to use\n */\nfunction booruForSite(site: string, credentials?: BooruCredentials): Booru {\n const rSite = resolveSite(site)\n\n if (!rSite) throw new BooruError('Site not supported')\n\n const booruSite = new Site(sites[rSite])\n\n // If special type, use that booru, else use default Booru\n return booruFrom(booruSite, credentials)\n}\n\nexport { booruForSite as forSite }\nexport default booruForSite\n\nexport interface BooruSearch extends SearchParameters {\n credentials?: BooruCredentials\n}\n\nexport interface BooruTagList extends TagListParameters {\n credentials?: BooruCredentials\n}\n\n/**\n * Searches a site for images with tags and returns the results\n * @param {String} site The site to search\n * @param {String[]|String} [tags=[]] Tags to search with\n * @param {SearchParameters} [searchOptions={}] The options for searching\n * if provided (Unused)\n * @return {Promise<SearchResults>} A promise with the images as an array of objects\n *\n * @example\n * ```\n * const Booru = require('booru')\n * // Returns a promise with the latest cute glace pic from e926\n * Booru.search('e926', ['glaceon', 'cute'])\n * ```\n */\nexport function search(\n site: string,\n tags: string[] | string = [],\n { limit = 1, random = false, page = 0, credentials = {} }: BooruSearch = {},\n): Promise<SearchResults> {\n const rSite = resolveSite(site)\n\n if (typeof limit === 'string') {\n limit = Number.parseInt(limit, 10)\n }\n\n if (rSite === null) {\n throw new BooruError('Site not supported')\n }\n\n if (!Array.isArray(tags) && typeof tags !== 'string') {\n throw new BooruError('`tags` should be an array or string')\n }\n\n if (typeof limit !== 'number' || Number.isNaN(limit)) {\n throw new BooruError('`limit` should be an int')\n }\n\n const booruSite = new Site(sites[rSite])\n\n if (!booruCache[rSite]) {\n booruCache[rSite] = booruFrom(booruSite, credentials)\n }\n\n // This is ugly and a hack, I know this\n booruCache[rSite].credentials = credentials\n return booruCache[rSite].search(tags, { limit, random, page })\n}\n\n/**\n * Get a list of tags from a site\n * @param {String} site The site to get the tags from\n * @param {TagListParameters} [options={}] The options for the tag list\n * @return {Promise<TagListResults>} A promise with the tags as an array of objects\n *\n * @example\n * ```\n * const Booru = require('booru')\n * // Returns a promise with the first 100 tags from e926\n * Booru.tagList('e926')\n * ```\n */\nexport function tagList(\n site: string,\n { limit = 1, page = 0, credentials = {} }: BooruTagList = {},\n): Promise<TagListResults> {\n const rSite = resolveSite(site)\n\n if (rSite === null) {\n throw new BooruError('Site not supported')\n }\n\n const booruSite = new Site(sites[rSite])\n\n if (!booruCache[rSite]) {\n booruCache[rSite] = booruFrom(booruSite, credentials)\n }\n\n booruCache[rSite].credentials = credentials\n return booruCache[rSite].tagList({ limit, page })\n}\n\nconst deprecatedCommonfy = deprecate(\n () => {},\n 'Common is now deprecated, just access the properties directly',\n)\n\n/**\n * Deprecated, now a noop\n * <p>This will be removed *soon* please stop using it</p>\n * <p>Just access <code><{@link Post}>.prop</code>, no need to commonfy anymore\n *\n * @deprecated Just use <code><{@link Post}>.prop</code> instead\n * @param {Post[]} images Array of {@link Post} objects\n * @return {Promise<Post[]>} Array of {@link Post} objects\n */\nexport function commonfy(images: Post[]): Promise<Post[]> {\n deprecatedCommonfy()\n return Promise.resolve(images)\n}\n\nexport { Booru as BooruClass } from './boorus/Booru'\nexport { BooruError, sites } from './Constants'\nexport { resolveSite } from './Utils'\nexport { Derpibooru, Post, SearchResults, Site, XmlBooru }\nexport type { BooruCredentials, SearchParameters }\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @packageDocumentation\n * @module Index\n */\n\nimport { deprecate } from 'node:util'\nimport Booru, { type BooruCredentials } from './boorus/Booru'\nimport Derpibooru from './boorus/Derpibooru'\nimport XmlBooru from './boorus/XmlBooru'\nimport { type AnySite, BooruError, sites } from './Constants'\nimport Post from './structures/Post'\nimport type SearchParameters from './structures/SearchParameters'\nimport SearchResults from './structures/SearchResults'\nimport Site from './structures/Site'\nimport type TagListParameters from './structures/TagListParameters'\nimport type TagListResults from './structures/TagListResults'\nimport { resolveSite } from './Utils'\n\nconst BooruTypes: Record<string, typeof Booru> = {\n derpi: Derpibooru,\n xml: XmlBooru,\n}\n\nconst booruCache: Partial<Record<AnySite, Booru>> = {}\n\n/**\n * Create a new booru, if special type, use that booru, else use default Booru\n *\n * @param booruSite The site to use\n * @param credentials The credentials to use, if any\n * @return A new booru\n */\nfunction booruFrom(booruSite: Site, credentials?: BooruCredentials): Booru {\n return new (\n booruSite.type !== undefined && BooruTypes[booruSite.type]\n ? BooruTypes[booruSite.type]\n : Booru\n )(booruSite, credentials)\n}\n\n/**\n * Create a new booru to search with\n *\n * @constructor\n * @param {String} site The {@link Site} domain (or alias of it) to create a booru from\n * @param {BooruCredentials} credentials The credentials to use on this booru\n * @return {Booru} A booru to use\n */\nfunction booruForSite(site: string, credentials?: BooruCredentials): Booru {\n const rSite = resolveSite(site)\n\n if (!rSite) throw new BooruError('Site not supported')\n\n const booruSite = new Site(sites[rSite])\n\n // If special type, use that booru, else use default Booru\n return booruFrom(booruSite, credentials)\n}\n\nexport { booruForSite as forSite }\nexport default booruForSite\n\nexport interface BooruSearch extends SearchParameters {\n credentials?: BooruCredentials\n}\n\nexport interface BooruPostCountOptions {\n credentials?: BooruCredentials\n}\n\nexport interface BooruTagList extends TagListParameters {\n credentials?: BooruCredentials\n}\n\n/**\n * Searches a site for images with tags and returns the results\n * @param {String} site The site to search\n * @param {String[]|String} [tags=[]] Tags to search with\n * @param {SearchParameters} [searchOptions={}] The options for searching\n * if provided (Unused)\n * @return {Promise<SearchResults>} A promise with the images as an array of objects\n *\n * @example\n * ```\n * const Booru = require('booru')\n * // Returns a promise with the latest cute glace pic from e926\n * Booru.search('e926', ['glaceon', 'cute'])\n * ```\n */\nexport function search(\n site: string,\n tags: string[] | string = [],\n { limit = 1, random = false, page = 0, credentials = {} }: BooruSearch = {},\n): Promise<SearchResults> {\n const rSite = resolveSite(site)\n\n if (typeof limit === 'string') {\n limit = Number.parseInt(limit, 10)\n }\n\n if (rSite === null) {\n throw new BooruError('Site not supported')\n }\n\n if (!Array.isArray(tags) && typeof tags !== 'string') {\n throw new BooruError('`tags` should be an array or string')\n }\n\n if (typeof limit !== 'number' || Number.isNaN(limit)) {\n throw new BooruError('`limit` should be an int')\n }\n\n const booruSite = new Site(sites[rSite])\n\n if (!booruCache[rSite]) {\n booruCache[rSite] = booruFrom(booruSite, credentials)\n }\n\n // This is ugly and a hack, I know this\n booruCache[rSite].credentials = credentials\n return booruCache[rSite].search(tags, { limit, random, page })\n}\n\n/**\n * Gets the total number of posts for specific tags\n * @param {String} site The site to search\n * @param {String[]|String} [tags=[]] Tags to check the count for\n * @param {BooruPostCountOptions} [options={}] The options (credentials)\n * @return {Promise<number>} A promise with the total number of posts\n *\n * @example\n * ```\n * const Booru = require('booru')\n * // Returns the total amount of posts for 'cat' on e926\n * const count = await Booru.postCount('e926', ['cat'])\n * ```\n */\nexport function postCount(\n site: string,\n tags: string[] | string = [],\n { credentials = {} }: BooruPostCountOptions = {},\n): Promise<number> {\n const rSite = resolveSite(site)\n\n if (rSite === null) {\n throw new BooruError('Site not supported')\n }\n\n if (!Array.isArray(tags) && typeof tags !== 'string') {\n throw new BooruError('`tags` should be an array or string')\n }\n\n const booruSite = new Site(sites[rSite])\n\n if (!booruCache[rSite]) {\n booruCache[rSite] = booruFrom(booruSite, credentials)\n }\n\n booruCache[rSite].credentials = credentials\n\n return booruCache[rSite]?.getPostCount(tags)\n}\n\n/**\n * Get a list of tags from a site\n * @param {String} site The site to get the tags from\n * @param {TagListParameters} [options={}] The options for the tag list\n * @return {Promise<TagListResults>} A promise with the tags as an array of objects\n *\n * @example\n * ```\n * const Booru = require('booru')\n * // Returns a promise with the first 100 tags from e926\n * Booru.tagList('e926')\n * ```\n */\nexport function tagList(\n site: string,\n { limit = 1, page = 0, credentials = {} }: BooruTagList = {},\n): Promise<TagListResults> {\n const rSite = resolveSite(site)\n\n if (rSite === null) {\n throw new BooruError('Site not supported')\n }\n\n const booruSite = new Site(sites[rSite])\n\n if (!booruCache[rSite]) {\n booruCache[rSite] = booruFrom(booruSite, credentials)\n }\n\n booruCache[rSite].credentials = credentials\n return booruCache[rSite].tagList({ limit, page })\n}\n\nconst deprecatedCommonfy = deprecate(\n () => {},\n 'Common is now deprecated, just access the properties directly',\n)\n\n/**\n * Deprecated, now a noop\n * <p>This will be removed *soon* please stop using it</p>\n * <p>Just access <code><{@link Post}>.prop</code>, no need to commonfy anymore\n *\n * @deprecated Just use <code><{@link Post}>.prop</code> instead\n * @param {Post[]} images Array of {@link Post} objects\n * @return {Promise<Post[]>} Array of {@link Post} objects\n */\nexport function commonfy(images: Post[]): Promise<Post[]> {\n deprecatedCommonfy()\n return Promise.resolve(images)\n}\n\nexport { Booru as BooruClass } from './boorus/Booru'\nexport { BooruError, sites } from './Constants'\nexport { resolveSite } from './Utils'\nexport { Derpibooru, Post, SearchResults, Site, XmlBooru }\nexport type { BooruCredentials, SearchParameters }\n"]}
|
package/dist/sites.json
CHANGED
|
@@ -26,7 +26,9 @@
|
|
|
26
26
|
"tagList": "/tags.json?"
|
|
27
27
|
},
|
|
28
28
|
"random": true,
|
|
29
|
-
"defaultTags": [
|
|
29
|
+
"defaultTags": [
|
|
30
|
+
"rating:safe"
|
|
31
|
+
]
|
|
30
32
|
},
|
|
31
33
|
"hypnohub.net": {
|
|
32
34
|
"domain": "hypnohub.net",
|
|
@@ -39,7 +41,8 @@
|
|
|
39
41
|
"api": {
|
|
40
42
|
"search": "/index.php?page=dapi&s=post&q=index&json=1&",
|
|
41
43
|
"postView": "/post/show/",
|
|
42
|
-
"tagList": "/index.php?page=dapi&s=tag&q=index&json=1&"
|
|
44
|
+
"tagList": "/index.php?page=dapi&s=tag&q=index&json=1&",
|
|
45
|
+
"postCount": "/index.php?page=dapi&s=post&q=index&"
|
|
43
46
|
},
|
|
44
47
|
"paginate": "pid",
|
|
45
48
|
"random": false
|
|
@@ -55,9 +58,11 @@
|
|
|
55
58
|
"api": {
|
|
56
59
|
"search": "/posts.json?",
|
|
57
60
|
"postView": "/posts/",
|
|
58
|
-
"tagList": "/tags.json?"
|
|
61
|
+
"tagList": "/tags.json?",
|
|
62
|
+
"postCount": "/counts/posts.json?"
|
|
59
63
|
},
|
|
60
|
-
"random": true
|
|
64
|
+
"random": true,
|
|
65
|
+
"postCountType": "json"
|
|
61
66
|
},
|
|
62
67
|
"konachan.com": {
|
|
63
68
|
"domain": "konachan.com",
|
|
@@ -70,7 +75,8 @@
|
|
|
70
75
|
"api": {
|
|
71
76
|
"search": "/post.json?",
|
|
72
77
|
"postView": "/post/show/",
|
|
73
|
-
"tagList": "/tag.json?"
|
|
78
|
+
"tagList": "/tag.json?",
|
|
79
|
+
"postCount": "/post.xml/?"
|
|
74
80
|
},
|
|
75
81
|
"random": true
|
|
76
82
|
},
|
|
@@ -85,7 +91,8 @@
|
|
|
85
91
|
"api": {
|
|
86
92
|
"search": "/post.json?",
|
|
87
93
|
"postView": "/post/show/",
|
|
88
|
-
"tagList": "/tag.json?"
|
|
94
|
+
"tagList": "/tag.json?",
|
|
95
|
+
"postCount": "/post.xml/?"
|
|
89
96
|
},
|
|
90
97
|
"random": true
|
|
91
98
|
},
|
|
@@ -100,7 +107,8 @@
|
|
|
100
107
|
"api": {
|
|
101
108
|
"search": "/post.json?",
|
|
102
109
|
"postView": "/post/show/",
|
|
103
|
-
"tagList": "/tag.json?"
|
|
110
|
+
"tagList": "/tag.json?",
|
|
111
|
+
"postCount": "/post.xml/?"
|
|
104
112
|
},
|
|
105
113
|
"random": true
|
|
106
114
|
},
|
|
@@ -115,7 +123,8 @@
|
|
|
115
123
|
"api": {
|
|
116
124
|
"search": "/index.php?page=dapi&s=post&q=index&json=1&",
|
|
117
125
|
"postView": "/index.php?page=post&s=view&json=1&id=",
|
|
118
|
-
"tagList": "/index.php?page=dapi&s=tag&q=index&json=1&"
|
|
126
|
+
"tagList": "/index.php?page=dapi&s=tag&q=index&json=1&",
|
|
127
|
+
"postCount": "/index.php?page=dapi&s=post&q=index&"
|
|
119
128
|
},
|
|
120
129
|
"paginate": "pid",
|
|
121
130
|
"random": false
|
|
@@ -130,7 +139,8 @@
|
|
|
130
139
|
"api": {
|
|
131
140
|
"search": "/index.php?page=dapi&s=post&q=index&json=1&",
|
|
132
141
|
"postView": "/index.php?page=post&s=view&json=1&id=",
|
|
133
|
-
"tagList": "/index.php?page=dapi&s=tag&q=index&json=1&"
|
|
142
|
+
"tagList": "/index.php?page=dapi&s=tag&q=index&json=1&",
|
|
143
|
+
"postCount": "/index.php?page=dapi&s=post&q=index&"
|
|
134
144
|
},
|
|
135
145
|
"paginate": "pid",
|
|
136
146
|
"random": false
|
|
@@ -146,7 +156,8 @@
|
|
|
146
156
|
"api": {
|
|
147
157
|
"search": "/index.php?page=dapi&s=post&q=index&json=1&",
|
|
148
158
|
"postView": "/index.php?page=post&s=view&json=1&id=",
|
|
149
|
-
"tagList": "/index.php?page=dapi&s=tag&q=index&json=1&"
|
|
159
|
+
"tagList": "/index.php?page=dapi&s=tag&q=index&json=1&",
|
|
160
|
+
"postCount": "/index.php?page=dapi&s=post&q=index&"
|
|
150
161
|
},
|
|
151
162
|
"paginate": "pid",
|
|
152
163
|
"random": false
|
|
@@ -177,7 +188,8 @@
|
|
|
177
188
|
"api": {
|
|
178
189
|
"search": "/index.php?page=dapi&s=post&q=index&json=1&",
|
|
179
190
|
"postView": "/index.php?page=post&s=view&json=1&id=",
|
|
180
|
-
"tagList": "/index.php?page=dapi&s=tag&q=index&json=1&"
|
|
191
|
+
"tagList": "/index.php?page=dapi&s=tag&q=index&json=1&",
|
|
192
|
+
"postCount": "/index.php?page=dapi&s=post&q=index&"
|
|
181
193
|
},
|
|
182
194
|
"paginate": "pid",
|
|
183
195
|
"random": false
|
|
@@ -192,7 +204,8 @@
|
|
|
192
204
|
"nsfw": true,
|
|
193
205
|
"api": {
|
|
194
206
|
"search": "/api/danbooru/find_posts?",
|
|
195
|
-
"postView": "/post/view/"
|
|
207
|
+
"postView": "/post/view/",
|
|
208
|
+
"postCount": "/api/danbooru/find_posts?"
|
|
196
209
|
},
|
|
197
210
|
"random": false
|
|
198
211
|
},
|
|
@@ -208,11 +221,13 @@
|
|
|
208
221
|
"nsfw": true,
|
|
209
222
|
"api": {
|
|
210
223
|
"search": "/api/v1/json/search/images?",
|
|
211
|
-
"postView": "/images/"
|
|
224
|
+
"postView": "/images/",
|
|
225
|
+
"postCount": "/api/v1/json/search/images?&per_page=1&"
|
|
212
226
|
},
|
|
213
227
|
"tagQuery": "q",
|
|
214
228
|
"tagJoin": ",",
|
|
215
|
-
"random": "sf=random"
|
|
229
|
+
"random": "sf=random",
|
|
230
|
+
"postCountType": "derpi"
|
|
216
231
|
},
|
|
217
232
|
"realbooru.com": {
|
|
218
233
|
"domain": "realbooru.com",
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* @packageDocumentation
|
|
3
3
|
* @module Structures
|
|
4
4
|
*/
|
|
5
|
+
import type { BooruCredentials } from '../boorus/Booru';
|
|
5
6
|
import type SearchParameters from './SearchParameters';
|
|
6
7
|
/**
|
|
7
8
|
* Interface for {@link Booru}'s **private internal** search params pls no use
|
|
@@ -13,5 +14,7 @@ export default interface InternalSearchParameters extends SearchParameters {
|
|
|
13
14
|
fakeLimit?: number;
|
|
14
15
|
/** The tags used in the search */
|
|
15
16
|
tags?: string[];
|
|
17
|
+
/** Credentials to use for the request */
|
|
18
|
+
credentials?: BooruCredentials;
|
|
16
19
|
}
|
|
17
20
|
//# sourceMappingURL=InternalSearchParameters.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InternalSearchParameters.d.ts","sourceRoot":"","sources":["../../src/structures/InternalSearchParameters.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,gBAAgB,MAAM,oBAAoB,CAAA;AAEtD;;GAEG;AAEH,MAAM,CAAC,OAAO,WAAW,wBAAyB,SAAQ,gBAAgB;IACxE,4CAA4C;IAC5C,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,kCAAkC;IAClC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;
|
|
1
|
+
{"version":3,"file":"InternalSearchParameters.d.ts","sourceRoot":"","sources":["../../src/structures/InternalSearchParameters.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AACvD,OAAO,KAAK,gBAAgB,MAAM,oBAAoB,CAAA;AAEtD;;GAEG;AAEH,MAAM,CAAC,OAAO,WAAW,wBAAyB,SAAQ,gBAAgB;IACxE,4CAA4C;IAC5C,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,kCAAkC;IAClC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;IACf,yCAAyC;IACzC,WAAW,CAAC,EAAE,gBAAgB,CAAA;CAC/B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InternalSearchParameters.js","sourceRoot":"","sources":["../../src/structures/InternalSearchParameters.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/**\n * @packageDocumentation\n * @module Structures\n */\n\nimport type SearchParameters from './SearchParameters'\n\n/**\n * Interface for {@link Booru}'s **private internal** search params pls no use\n */\n\nexport default interface InternalSearchParameters extends SearchParameters {\n /** The uri to override with, if provided */\n uri?: string | null\n /** If `order:random` should be faked */\n fakeLimit?: number\n /** The tags used in the search */\n tags?: string[]\n}\n"]}
|
|
1
|
+
{"version":3,"file":"InternalSearchParameters.js","sourceRoot":"","sources":["../../src/structures/InternalSearchParameters.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/**\n * @packageDocumentation\n * @module Structures\n */\n\nimport type { BooruCredentials } from '../boorus/Booru'\nimport type SearchParameters from './SearchParameters'\n\n/**\n * Interface for {@link Booru}'s **private internal** search params pls no use\n */\n\nexport default interface InternalSearchParameters extends SearchParameters {\n /** The uri to override with, if provided */\n uri?: string | null\n /** If `order:random` should be faked */\n fakeLimit?: number\n /** The tags used in the search */\n tags?: string[]\n /** Credentials to use for the request */\n credentials?: BooruCredentials\n}\n"]}
|
|
@@ -11,7 +11,9 @@ export default class Site {
|
|
|
11
11
|
/** The domain of the Site (the "google.com" part of "https://google.com/foo") */
|
|
12
12
|
domain: string;
|
|
13
13
|
/** The type of this site (json/xml/derpi) */
|
|
14
|
-
type:
|
|
14
|
+
type: 'json' | 'xml' | 'derpi';
|
|
15
|
+
/** The type of post count this site uses, if any */
|
|
16
|
+
postCountType: 'json' | 'xml' | 'derpi';
|
|
15
17
|
/** The aliases of this site */
|
|
16
18
|
aliases: string[];
|
|
17
19
|
/** If this site serves NSFW posts or not */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Site.d.ts","sourceRoot":"","sources":["../../src/structures/Site.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,OAAO,MAAM,WAAW,CAAA;AACpC,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAA;AAEtC;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,IAAI;IACvB,iFAAiF;IAC1E,MAAM,EAAE,MAAM,CAAA;IACrB,6CAA6C;
|
|
1
|
+
{"version":3,"file":"Site.d.ts","sourceRoot":"","sources":["../../src/structures/Site.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,OAAO,MAAM,WAAW,CAAA;AACpC,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAA;AAEtC;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,IAAI;IACvB,iFAAiF;IAC1E,MAAM,EAAE,MAAM,CAAA;IACrB,6CAA6C;IAC7C,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,OAAO,CAAA;IAC9B,oDAAoD;IACpD,aAAa,EAAE,MAAM,GAAG,KAAK,GAAG,OAAO,CAAA;IACvC,+BAA+B;IACxB,OAAO,EAAE,MAAM,EAAE,CAAA;IACxB,4CAA4C;IACrC,IAAI,EAAE,OAAO,CAAA;IACpB,kDAAkD;IAC3C,GAAG,EAAE,OAAO,CAAA;IACnB,kDAAkD;IAC3C,QAAQ,EAAE,MAAM,CAAA;IACvB;;;OAGG;IACI,MAAM,EAAE,OAAO,GAAG,MAAM,CAAA;IAC/B,mCAAmC;IAC5B,QAAQ,EAAE,MAAM,CAAA;IACvB,qEAAqE;IAC9D,OAAO,EAAE,MAAM,CAAA;IACtB,yCAAyC;IAClC,QAAQ,EAAE,OAAO,CAAA;IACxB,oDAAoD;IAC7C,WAAW,EAAE,MAAM,EAAE,CAAA;gBAEhB,IAAI,EAAE,QAAQ;CAc3B"}
|
package/dist/structures/Site.js
CHANGED
|
@@ -12,6 +12,8 @@ class Site {
|
|
|
12
12
|
domain;
|
|
13
13
|
/** The type of this site (json/xml/derpi) */
|
|
14
14
|
type;
|
|
15
|
+
/** The type of post count this site uses, if any */
|
|
16
|
+
postCountType;
|
|
15
17
|
/** The aliases of this site */
|
|
16
18
|
aliases;
|
|
17
19
|
/** If this site serves NSFW posts or not */
|
|
@@ -36,6 +38,7 @@ class Site {
|
|
|
36
38
|
constructor(data) {
|
|
37
39
|
this.domain = data.domain;
|
|
38
40
|
this.type = data.type ?? 'json';
|
|
41
|
+
this.postCountType = data.postCountType ?? 'xml';
|
|
39
42
|
this.aliases = data.aliases ?? [];
|
|
40
43
|
this.nsfw = data.nsfw;
|
|
41
44
|
this.api = data.api ?? {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Site.js","sourceRoot":"","sources":["../../src/structures/Site.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAKH;;GAEG;AACH,MAAqB,IAAI;IACvB,iFAAiF;IAC1E,MAAM,CAAQ;IACrB,6CAA6C;
|
|
1
|
+
{"version":3,"file":"Site.js","sourceRoot":"","sources":["../../src/structures/Site.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAKH;;GAEG;AACH,MAAqB,IAAI;IACvB,iFAAiF;IAC1E,MAAM,CAAQ;IACrB,6CAA6C;IAC7C,IAAI,CAA0B;IAC9B,oDAAoD;IACpD,aAAa,CAA0B;IACvC,+BAA+B;IACxB,OAAO,CAAU;IACxB,4CAA4C;IACrC,IAAI,CAAS;IACpB,kDAAkD;IAC3C,GAAG,CAAS;IACnB,kDAAkD;IAC3C,QAAQ,CAAQ;IACvB;;;OAGG;IACI,MAAM,CAAkB;IAC/B,mCAAmC;IAC5B,QAAQ,CAAQ;IACvB,qEAAqE;IAC9D,OAAO,CAAQ;IACtB,yCAAyC;IAClC,QAAQ,CAAS;IACxB,oDAAoD;IAC7C,WAAW,CAAU;IAE5B,YAAY,IAAc;QACxB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAA;QACzB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,MAAM,CAAA;QAC/B,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,IAAI,KAAK,CAAA;QAChD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,EAAE,CAAA;QACjC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;QACrB,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,EAAE,CAAA;QACzB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,MAAM,CAAA;QACvC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,KAAK,CAAA;QAClC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,MAAM,CAAA;QACvC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,GAAG,CAAA;QAClC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAA;QACtC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,IAAI,EAAE,CAAA;IAC3C,CAAC;CACF;AA3CD,uBA2CC","sourcesContent":["/**\n * @packageDocumentation\n * @module Structures\n */\n\nimport type SiteApi from './SiteApi'\nimport type SiteInfo from './SiteInfo'\n\n/**\n * Represents a site, mostly used for JSDoc\n */\nexport default class Site {\n /** The domain of the Site (the \"google.com\" part of \"https://google.com/foo\") */\n public domain: string\n /** The type of this site (json/xml/derpi) */\n type: 'json' | 'xml' | 'derpi'\n /** The type of post count this site uses, if any */\n postCountType: 'json' | 'xml' | 'derpi'\n /** The aliases of this site */\n public aliases: string[]\n /** If this site serves NSFW posts or not */\n public nsfw: boolean\n /** An object representing the api of this site */\n public api: SiteApi\n /** The url query param to paginate on the site */\n public paginate: string\n /**\n * If the site supports `order:random`.\n * If a string, this means a custom random system is used :/\n */\n public random: boolean | string\n /** The url query param for tags */\n public tagQuery: string\n /** The character to use to join tags when creating the search url */\n public tagJoin: string\n /** If this site supports only http:// */\n public insecure: boolean\n /** Tags to add to every request, if not included */\n public defaultTags: string[]\n\n constructor(data: SiteInfo) {\n this.domain = data.domain\n this.type = data.type ?? 'json'\n this.postCountType = data.postCountType ?? 'xml'\n this.aliases = data.aliases ?? []\n this.nsfw = data.nsfw\n this.api = data.api ?? {}\n this.paginate = data.paginate ?? 'page'\n this.random = data.random ?? false\n this.tagQuery = data.tagQuery ?? 'tags'\n this.tagJoin = data.tagJoin ?? '+'\n this.insecure = data.insecure ?? false\n this.defaultTags = data.defaultTags ?? []\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SiteApi.d.ts","sourceRoot":"","sources":["../../src/structures/SiteApi.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,MAAM,CAAC,OAAO,WAAW,OAAO;IAC9B,mCAAmC;IACnC,MAAM,EAAE,MAAM,CAAA;IACd,oCAAoC;IACpC,QAAQ,EAAE,MAAM,CAAA;IAChB,0CAA0C;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"SiteApi.d.ts","sourceRoot":"","sources":["../../src/structures/SiteApi.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,MAAM,CAAC,OAAO,WAAW,OAAO;IAC9B,mCAAmC;IACnC,MAAM,EAAE,MAAM,CAAA;IACd,oCAAoC;IACpC,QAAQ,EAAE,MAAM,CAAA;IAChB,0CAA0C;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SiteApi.js","sourceRoot":"","sources":["../../src/structures/SiteApi.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/**\n * @packageDocumentation\n * @module Structures\n */\n\n/**\n * Represents the api of a {@link Site}\n * <p>Each property is a path on the {@link Site}\n */\nexport default interface SiteApi {\n /** The path to search for posts */\n search: string\n /** The path to view a post by ID */\n postView: string\n /** The path to retrieve a list of tags */\n tagList?: string\n}\n"]}
|
|
1
|
+
{"version":3,"file":"SiteApi.js","sourceRoot":"","sources":["../../src/structures/SiteApi.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/**\n * @packageDocumentation\n * @module Structures\n */\n\n/**\n * Represents the api of a {@link Site}\n * <p>Each property is a path on the {@link Site}\n */\nexport default interface SiteApi {\n /** The path to search for posts */\n search: string\n /** The path to view a post by ID */\n postView: string\n /** The path to retrieve a list of tags */\n tagList?: string\n /** The path to retrieve the count of posts with tags */\n postCount?: string\n}\n"]}
|
|
@@ -12,7 +12,9 @@ export default interface SiteInfo {
|
|
|
12
12
|
/** The domain of the Site (the "google.com" part of "https://google.com/foo") */
|
|
13
13
|
domain: string;
|
|
14
14
|
/** The type of this site (json/xml/derpi) */
|
|
15
|
-
type:
|
|
15
|
+
type: 'json' | 'xml' | 'derpi';
|
|
16
|
+
/** The type of post count this site uses, if any */
|
|
17
|
+
postCountType: 'json' | 'xml' | 'derpi';
|
|
16
18
|
/** The aliases of this site */
|
|
17
19
|
aliases: string[];
|
|
18
20
|
/** If this site serves NSFW posts or not */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SiteInfo.d.ts","sourceRoot":"","sources":["../../src/structures/SiteInfo.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,OAAO,MAAM,WAAW,CAAA;AAEpC;;;;GAIG;AACH,MAAM,CAAC,OAAO,WAAW,QAAQ;IAC/B,iFAAiF;IACjF,MAAM,EAAE,MAAM,CAAA;IACd,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"SiteInfo.d.ts","sourceRoot":"","sources":["../../src/structures/SiteInfo.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,OAAO,MAAM,WAAW,CAAA;AAEpC;;;;GAIG;AACH,MAAM,CAAC,OAAO,WAAW,QAAQ;IAC/B,iFAAiF;IACjF,MAAM,EAAE,MAAM,CAAA;IACd,6CAA6C;IAC7C,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,OAAO,CAAA;IAC9B,oDAAoD;IACpD,aAAa,EAAE,MAAM,GAAG,KAAK,GAAG,OAAO,CAAA;IACvC,+BAA+B;IAC/B,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,4CAA4C;IAC5C,IAAI,EAAE,OAAO,CAAA;IACb,kDAAkD;IAClD,GAAG,EAAE,OAAO,CAAA;IACZ,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,0CAA0C;IAC1C,MAAM,EAAE,OAAO,GAAG,MAAM,CAAA;IACxB,mCAAmC;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,yCAAyC;IACzC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,oDAAoD;IACpD,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;CACvB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SiteInfo.js","sourceRoot":"","sources":["../../src/structures/SiteInfo.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/**\n * @packageDocumentation\n * @module Structures\n */\n\nimport type SiteApi from './SiteApi'\n\n/**\n * Represents the info needed to create a new {@link Site}\n * <p>Same properties as {@link Site}, but some optional</p>\n * <p>Mostly just here to reflect what sites.json should look like\n */\nexport default interface SiteInfo {\n /** The domain of the Site (the \"google.com\" part of \"https://google.com/foo\") */\n domain: string\n /** The type of this site (json/xml/derpi) */\n type:
|
|
1
|
+
{"version":3,"file":"SiteInfo.js","sourceRoot":"","sources":["../../src/structures/SiteInfo.ts"],"names":[],"mappings":";AAAA;;;GAGG","sourcesContent":["/**\n * @packageDocumentation\n * @module Structures\n */\n\nimport type SiteApi from './SiteApi'\n\n/**\n * Represents the info needed to create a new {@link Site}\n * <p>Same properties as {@link Site}, but some optional</p>\n * <p>Mostly just here to reflect what sites.json should look like\n */\nexport default interface SiteInfo {\n /** The domain of the Site (the \"google.com\" part of \"https://google.com/foo\") */\n domain: string\n /** The type of this site (json/xml/derpi) */\n type: 'json' | 'xml' | 'derpi'\n /** The type of post count this site uses, if any */\n postCountType: 'json' | 'xml' | 'derpi'\n /** The aliases of this site */\n aliases: string[]\n /** If this site serves NSFW posts or not */\n nsfw: boolean\n /** An object representing the api of this site */\n api: SiteApi\n /** The url query param to paginate on the site */\n paginate?: string\n /** If the site supports `order:random` */\n random: boolean | string\n /** The url query param for tags */\n tagQuery?: string\n /** The character to use to join tags when creating the search url */\n tagJoin?: string\n /** If this site supports only http:// */\n insecure?: boolean\n /** Tags to add to every request, if not included */\n defaultTags?: string[]\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "booru",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.9.0",
|
|
4
4
|
"description": "Search (and do other things) on a bunch of different boorus!",
|
|
5
5
|
"author": "AtoraSuunva (https://github.com/AtoraSuunva/)",
|
|
6
6
|
"license": "MIT",
|
|
@@ -33,14 +33,14 @@
|
|
|
33
33
|
"node": ">=20"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"fast-xml-parser": "^5.
|
|
37
|
-
"undici": "^7.
|
|
36
|
+
"fast-xml-parser": "^5.3.7",
|
|
37
|
+
"undici": "^7.22.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@biomejs/biome": "^2.
|
|
41
|
-
"@types/node": "^24.
|
|
42
|
-
"tsx": "^4.
|
|
43
|
-
"typescript": "^5.
|
|
40
|
+
"@biomejs/biome": "^2.4.4",
|
|
41
|
+
"@types/node": "^24.10.13",
|
|
42
|
+
"tsx": "^4.21.0",
|
|
43
|
+
"typescript": "^5.9.3"
|
|
44
44
|
},
|
|
45
45
|
"files": [
|
|
46
46
|
"dist/"
|