booru 2.8.0 → 2.8.2

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.
@@ -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 (Currently not used)
50
+ * @param credentials Credentials for the API
51
51
  */
52
52
  constructor(site: Site, credentials?: BooruCredentials);
53
53
  protected normalizeTags(tags: string | string[]): string[];
@@ -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 (Currently not used)
56
+ * @param credentials Credentials for the API
57
57
  */
58
58
  constructor(site, credentials) {
59
59
  const domain = (0, Utils_1.resolveSite)(site.domain);
@@ -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":";AAAA;;;GAGG;;;;;;AAEH,mCAA8B;AAC9B,4CAAgF;AAEhF,8DAAqC;AAErC,gFAAuD;AAEvD,4DAAmC;AACnC,kFAAyD;AACzD,oCAMiB;AAMjB,MAAM,aAAa,GACjB,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,cAAK,CAAA;AAenE;;;;;;GAMG;AAEH;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAa,KAAK;IAChB,8BAA8B;IACvB,MAAM,CAAQ;IACrB,8CAA8C;IACvC,IAAI,CAAM;IACjB,4CAA4C;IACrC,WAAW,CAA+B;IAEjD;;;;;;OAMG;IACH,YAAY,IAAU,EAAE,WAA8B;QACpD,MAAM,MAAM,GAAG,IAAA,mBAAW,EAAC,IAAI,CAAC,MAAM,CAAC,CAAA;QAEvC,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,wBAAwB,IAAI,CAAC,MAAM,EAAE,CAAC,CAAA;QACxD,CAAC;QAED,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QACpB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAA;IAChC,CAAC;IAES,aAAa,CAAC,IAAuB;QAC7C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,IAAI,CAAC,CAAA;QACf,CAAC;QAED,OAAO,IAAI,CAAC,KAAK,EAAE,CAAA;IACrB,CAAC;IAED;;;;;OAKG;IACI,KAAK,CAAC,MAAM,CACjB,IAAuB,EACvB,EACE,KAAK,GAAG,CAAC,EACT,MAAM,GAAG,KAAK,EACd,IAAI,GAAG,CAAC,EACR,eAAe,GAAG,KAAK,MACH,EAAE;QAExB,MAAM,SAAS,GAAW,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;QAC/D,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAA;QAEzC,IAAI,CAAC;YACH,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE;gBACxD,KAAK;gBACL,MAAM;gBACN,IAAI;gBACJ,eAAe;aAChB,CAAC,CAAA;YACF,OAAO,IAAI,CAAC,iBAAiB,CAAC,YAAY,EAAE;gBAC1C,SAAS;gBACT,IAAI,EAAE,QAAQ;gBACd,KAAK;gBACL,MAAM;gBACN,IAAI;gBACJ,eAAe;aAChB,CAAC,CAAA;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;gBACzB,MAAM,IAAI,sBAAU,CAAC,GAAG,CAAC,CAAA;YAC3B,CAAC;YAED,MAAM,GAAG,CAAA;QACX,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACI,QAAQ,CAAC,EAAmB;QACjC,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC;YACpE,MAAM,IAAI,sBAAU,CAAC,gCAAgC,EAAE,EAAE,CAAC,CAAA;QAC5D,CAAC;QAED,OAAO,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,CAAC,MAAM,GAC1D,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAChB,GAAG,EAAE,EAAE,CAAA;IACT,CAAC;IAED;;;;;;OAMG;IACI,KAAK,CAAC,OAAO,CAAC,EACnB,KAAK,GAAG,GAAG,EACX,IAAI,GAAG,CAAC,MACkB,EAAE;QAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;QAC/C,MAAM,OAAO,GAAG,0BAAc,CAAA;QAC9B,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;YAElD,oCAAoC;YACpC,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBAC5B,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,CAAA;gBAC1C,IAAI,IAAI,CAAC,QAAQ,CAAC,yBAAyB,CAAC,EAAE,CAAC;oBAC7C,MAAM,IAAI,sBAAU,CAClB,oEAAoE,CACrE,CAAA;gBACH,CAAC;YACH,CAAC;YAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,IAAI,sBAAU,CAClB,iBAAiB,QAAQ,CAAC,MAAM,iBAAiB,MAAM,QAAQ,CAAC,IAAI,EAAE,GAAG,CAC1E,CAAA;YACH,CAAC;YAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;YAClC;;;gBAGI;YACJ,IAAI,IAAI,GAAG,EAAE,CAAA;YACb,IAAI,CAAC;gBACH,IAAI,GAAG,IAAA,oBAAY,EAAC,IAAI,CAAC,CAAA;YAC3B,CAAC;YAAC,OAAO,EAAE,EAAE,CAAC;gBACZ,IAAI,GAAG,IAAA,mBAAW,EAAC,IAAI,CAAC,CAAA;YAC1B,CAAC;YAED,OAAO,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;QACvD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAK,GAAW,CAAC,IAAI,KAAK,cAAc;gBACtC,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;oBACzB,MAAM,IAAI,sBAAU,CAAC,GAAG,CAAC,CAAA;gBAC3B,CAAC;YAEH,MAAM,GAAG,CAAA;QACX,CAAC;IACH,CAAC;IAED;;;;;;;OAOG;IACO,KAAK,CAAC,eAAe,CAC7B,IAAc,EACd,EACE,GAAG,GAAG,IAAI,EACV,KAAK,GAAG,CAAC,EACT,MAAM,GAAG,KAAK,EACd,IAAI,GAAG,CAAC,MACoB,EAAE;QAEhC,gDAAgD;QAChD,IAAI,SAA6B,CAAA;QACjC,IAAI,UAAU,GAAG,IAAI,CAAC,KAAK,EAAE,CAAA;QAE7B,IAAI,MAAM,EAAE,CAAC;YACX,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACrB,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;YACjC,CAAC;iBAAM,CAAC;gBACN,SAAS,GAAG,GAAG,CAAA;YACjB,CAAC;QACH,CAAC;QAED,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YAC1B,UAAU,GAAG,UAAU,CAAC,MAAM,CAC5B,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAC7D,CAAA;QACH,CAAC;QAED,MAAM,QAAQ,GACZ,GAAG;YACH,IAAI,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,IAAI,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;QAC1E,MAAM,OAAO,GAAG,0BAAc,CAAA;QAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,KAAK,CAAA;QAEpC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;YAEvD,oCAAoC;YACpC,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBAC5B,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,CAAA;gBAC1C,IAAI,IAAI,CAAC,QAAQ,CAAC,yBAAyB,CAAC,EAAE,CAAC;oBAC7C,MAAM,IAAI,sBAAU,CAClB,oEAAoE,CACrE,CAAA;gBACH,CAAC;YACH,CAAC;YAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;YAClC,MAAM,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,IAAA,oBAAY,EAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAA,oBAAY,EAAC,IAAI,CAAC,CAAA;YAE3D,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,IAAI,sBAAU,CAClB,iBAAiB,QAAQ,CAAC,MAAM,GAAG;oBACjC,gBACG,KAAa,CAAC,KAAK;wBACnB,KAAa,CAAC,OAAO;wBACtB,IAAI,CAAC,SAAS,CAAC,KAAK,CACtB,GAAG,CACN,CAAA;YACH,CAAC;YAED,OAAO,KAAK,CAAA;QACd,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAK,GAAW,CAAC,IAAI,KAAK,cAAc;gBAAE,OAAO,EAAE,CAAA;YACnD,MAAM,GAAG,CAAA;QACX,CAAC;IACH,CAAC;IAED;;;;;;;OAOG;IACH,YAAY,CAAC,EACX,IAAI,GAAG,EAAE,EACT,KAAK,GAAG,GAAG,EACX,IAAI,GAAG,CAAC,MACoB,EAAE;QAC9B,OAAO,IAAA,qBAAS,EAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAA;IAClE,CAAC;IAED;;;;;;OAMG;IACH,aAAa,CAAC,EACZ,KAAK,GAAG,GAAG,EACX,IAAI,GAAG,CAAC,MACkB,EAAE;QAC5B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;YAC3B,MAAM,IAAI,sBAAU,CAClB,4CAA4C,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAC/D,CAAA;QACH,CAAC;QACD,OAAO,IAAA,sBAAU,EAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAA;IAC7D,CAAC;IAED;;;;;;;OAOG;IACO,iBAAiB,CACzB,MAAW,EACX,EACE,SAAS,EACT,IAAI,EACJ,KAAK,EACL,MAAM,EACN,IAAI,EACJ,eAAe,GACU;QAE3B,IAAI,SAAS,GAAG,MAAM,CAAA;QAEtB,IAAI,SAAS,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;YAChC,MAAM,IAAI,sBAAU,CAAC,SAAS,CAAC,OAAO,IAAI,SAAS,CAAC,MAAM,CAAC,CAAA;QAC7D,CAAC;QAED,WAAW;QACX,IAAI,SAAS,CAAC,aAAa,CAAC,EAAE,CAAC;YAC7B,MAAM,UAAU,GAAG,SAAS,CAAC,aAAa,CAAC,CAAA;YAE3C,IAAI,UAAU,CAAC,KAAK,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;gBAChD,SAAS,GAAG,EAAE,CAAA;YAChB,CAAC;iBAAM,IAAI,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;gBACzC,SAAS,GAAG,SAAS,CAAC,IAAI,CAAA;YAC5B,CAAC;iBAAM,CAAC;gBACN,SAAS,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;YAC9B,CAAC;QACH,CAAC;QAED,IAAI,SAAS,CAAC,KAAK,EAAE,CAAC;YACpB,SAAS,GAAG,SAAS,CAAC,KAAK,CAAA;QAC7B,CAAC;QAED,IAAI,SAAS,CAAC,MAAM,EAAE,CAAC;YACrB,SAAS,GAAG,SAAS,CAAC,MAAM,CAAA;QAC9B,CAAC;QAED,IAAI,CAAuB,CAAA;QAC3B,gFAAgF;QAChF,IAAI,SAAS,KAAK,EAAE,EAAE,CAAC;YACrB,CAAC,GAAG,EAAE,CAAA;QACR,CAAC;aAAM,IAAI,SAAS,EAAE,CAAC;YACrB,CAAC,GAAG,IAAA,eAAO,EAAC,SAAS,CAAC,CAAA;QACxB,CAAC;aAAM,IAAI,SAAS,CAAC,WAAW,KAAK,MAAM,EAAE,CAAC;YAC5C,sBAAsB;YACtB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;QACjB,CAAC;QAED,IAAI,KAAK,GAAW,CAAC,CAAC,IAAI,SAAS,CAAC;aACjC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC;aACf,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,IAAI,cAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAA;QACrC,MAAM,OAAO,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,CAAA;QAExD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,IAAI,GAAG,EAAE,CAAA;QACX,CAAC;QAED,IAAI,CAAC,eAAe,EAAE,CAAC;YACrB,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAA;QAC1C,CAAC;QAED,OAAO,IAAI,uBAAa,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,CAAA;IACtD,CAAC;IAED;;;;;;OAMG;IACO,kBAAkB,CAC1B,MAAW,EACX,EAAE,KAAK,GAAG,GAAG,EAAE,IAAI,GAAG,CAAC,KAA6B,EAAE;QAEtD,IAAI,MAAM,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;YAC7B,MAAM,IAAI,sBAAU,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,MAAM,CAAC,CAAA;QACvD,CAAC;QAED,IAAI,IAAI,GAAU,EAAE,CAAA;QAEpB,IAAI,MAAM,EAAE,CAAC;YACX,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC1B,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,aAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAA;YAC5C,CAAC;iBAAM,CAAC;gBACN,IAAI,GAAG,CAAC,IAAI,aAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAA;YAChC,CAAC;QACH,CAAC;QAED,OAAO,IAAI,wBAAc,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,IAAI,CAAC,CAAA;IACxD,CAAC;CACF;AAtWD,sBAsWC;AAED,kBAAe,KAAK,CAAA","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\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"]}
package/dist/sites.json CHANGED
@@ -26,7 +26,9 @@
26
26
  "tagList": "/tags.json?"
27
27
  },
28
28
  "random": true,
29
- "defaultTags": ["rating:safe"]
29
+ "defaultTags": [
30
+ "rating:safe"
31
+ ]
30
32
  },
31
33
  "hypnohub.net": {
32
34
  "domain": "hypnohub.net",
@@ -2,6 +2,7 @@
2
2
  * @packageDocumentation
3
3
  * @module Structures
4
4
  */
5
+ import { 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;CAChB"}
1
+ {"version":3,"file":"InternalSearchParameters.d.ts","sourceRoot":"","sources":["../../src/structures/InternalSearchParameters.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAClD,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 { 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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "booru",
3
- "version": "2.8.0",
3
+ "version": "2.8.2",
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.2.5",
37
- "undici": "^7.2.0"
36
+ "fast-xml-parser": "^5.3.4",
37
+ "undici": "^7.20.0"
38
38
  },
39
39
  "devDependencies": {
40
- "@biomejs/biome": "^2.0.5",
41
- "@types/node": "^24.0.3",
42
- "tsx": "^4.19.2",
43
- "typescript": "^5.7.2"
40
+ "@biomejs/biome": "^2.3.13",
41
+ "@types/node": "24",
42
+ "tsx": "^4.21.0",
43
+ "typescript": "^5.9.3"
44
44
  },
45
45
  "files": [
46
46
  "dist/"
package/readme.md CHANGED
@@ -2,13 +2,14 @@
2
2
 
3
3
  > _A node package to search boorus_
4
4
 
5
- ![npm](https://img.shields.io/npm/v/booru.svg) ![GitHub](https://img.shields.io/github/license/AtoraSuunva/booru.svg) ![Typescript typings](https://img.shields.io/badge/Typings-Typescript-informational.svg)
5
+ [![Lint and Test](https://github.com/AtoraSuunva/booru/actions/workflows/lint-and-test.yml/badge.svg)](https://github.com/AtoraSuunva/booru/actions/workflows/lint-and-test.yml) ![npm](https://img.shields.io/npm/v/booru.svg) ![GitHub](https://img.shields.io/github/license/AtoraSuunva/booru.svg) ![Typescript typings](https://img.shields.io/badge/Typings-Typescript-informational.svg)
6
6
 
7
7
  Only [non-EoL](https://nodejs.org/en/about/previous-releases) versions of Node.js are tested and officially supported. EoL versions are unsupported. Other runtimes (like web, Deno, and Bun) aren't _officially_ supported but issues and PRs are accepted for them.
8
8
 
9
9
  ## Features
10
10
 
11
- - Search 15 different boorus (check [sites.json](./src/sites.json))
11
+ - Search posts on 15 different boorus (check [sites.json](./src/sites.json))
12
+ - Search tags on 12 different boorus
12
13
  - Normalizes all received data into `Post` objects that are consistent no matter which booru you use
13
14
  - Access to the raw data received from the booru as well (transformed from XML to JSON, if applicable)
14
15
  - Alias support for boorus (`sb` for `safebooru.org`)
@@ -16,20 +17,29 @@ Only [non-EoL](https://nodejs.org/en/about/previous-releases) versions of Node.j
16
17
  - Types (using Typescript)
17
18
  - Choose the amount of images to get
18
19
  - Random support for all sites, using `order:random` on sites that support it and using custom code on those that don't
19
- - Coming soon(-ish): Support for more than just searching
20
20
 
21
21
  ---
22
22
 
23
23
  ## Installation
24
24
 
25
+ Booru is available on [npm](https://www.npmjs.com/package/booru):
26
+
25
27
  ```sh
28
+ # Pick your favorite package manager
26
29
  npm add booru
27
- # or
28
30
  pnpm add booru
29
- # or
30
31
  yarn add booru
31
32
  ```
32
33
 
34
+ And available on [jsr](https://jsr.io/@atorasuunva/booru):
35
+
36
+ ```sh
37
+ # Pick your favorite runtime
38
+ pnpm i jsr:@atorasuunva/booru
39
+ deno add jsr:@atorasuunva/booru
40
+ bunx jsr add @atorasuunva/booru
41
+ ```
42
+
33
43
  ---
34
44
 
35
45
  ## Usage
@@ -67,7 +77,7 @@ See [example.js](./example.js) for more examples
67
77
 
68
78
  ## Docs
69
79
 
70
- Available here: [https://booru.js.org](https://booru.js.org)
80
+ Available here: [https://jsr.io/@atorasuunva/booru/doc](https://jsr.io/@atorasuunva/booru/doc)
71
81
 
72
82
  ## Web support
73
83