diff --git a/mod.ts b/mod.ts index 2db3dc2..e301b48 100644 --- a/mod.ts +++ b/mod.ts @@ -4,4 +4,5 @@ export default AO3; import Chapter from "./src/classes/Chapter.ts"; import Search from "./src/classes/Search.ts"; import Work from "./src/classes/Work.ts"; -export { AO3, Chapter, Search, Work }; +const VERSION = "v0.2.0"; +export { AO3, Chapter, Search, VERSION, Work }; diff --git a/src/classes/AO3.ts b/src/classes/AO3.ts index 7ce7d2e..75e6af4 100644 --- a/src/classes/AO3.ts +++ b/src/classes/AO3.ts @@ -3,73 +3,23 @@ import { ID } from "../types.d.ts"; import { DOMParser } from "https://deno.land/x/deno_dom@v0.1.36-alpha/deno-dom-wasm.ts"; import { HTMLDocument } from "../types.d.ts"; import Search, { SearchParameters } from "./Search.ts"; -import { - CookieJar, - wrapFetch, -} from "https://deno.land/x/another_cookiejar@v5.0.1/mod.ts"; +import { newSession, Options } from "../utils/http.ts"; export default class AO3 { - session: { - get: (path: string) => Promise; - post: ( - path: string, - payload: unknown, - ) => Promise; - }; + session: ReturnType; DOMParser = new DOMParser(); - fetch: typeof fetch; - cookieJar: CookieJar; - #headers: Record; /** * a representation of AO3 in class form */ - constructor(opts?: { - url?: string; - }) { - this.cookieJar = new CookieJar(); - this.fetch = wrapFetch({ cookieJar: this.cookieJar }); - this.#headers = { - "User-Agent": - "Mozilla/5.0 (Windows NT 10.0; rv:108.0) Gecko/20100101 Firefox/108.0", - }; - this.session = { - get: async (path: string) => { - const res = await this.fetch( - opts?.url ?? "https://archiveofourown.org/" + path, - { - headers: this.#headers, - }, - ); - if (res.status > 300) { - console.log(res); - throw new Error("Failed request, probably rate-limited"); - } - return res; - }, - - post: async ( - path: string, - // deno-lint-ignore no-explicit-any - payload: any, - headers?: string, - ) => { - const res = await this.fetch( - opts?.url ?? "https://archiveofourown.org/" + path, - { - "credentials": "include", - headers: Object.assign(headers ?? {}, this.#headers), - method: "POST", - body: payload, - }, - ); - if (res.status > 300) { - console.log(res); - throw new Error("Failed request, probably rate-limited"); - } - return res; - }, - }; + constructor(opts?: Options) { + if (opts && !opts.headers) { + opts.headers = { + "User-Agent": + "Mozilla/5.0 (Windows NT 10.0; rv:108.0) Gecko/20100101 Firefox/108.0", + }; + } + this.session = newSession(opts ?? {}); } /** diff --git a/src/utils/http.ts b/src/utils/http.ts new file mode 100644 index 0000000..06b2faa --- /dev/null +++ b/src/utils/http.ts @@ -0,0 +1,66 @@ +// custom fetch wrappers.. for reasons +import { + CookieJar, + wrapFetch, +} from "https://deno.land/x/another_cookiejar@v5.0.1/mod.ts"; + +const cookieJar = new CookieJar(); + +const wrappedFetch = wrapFetch({ + cookieJar, +}); + +const defaultOptions = { + url: "https://archiveofourown.org/", + headers: { + "User-Agent": + `Mozilla/5.0 (Windows NT 10.0; rv:108.0) Gecko/20100101 Firefox/108.0`, + }, +}; + +export interface Options { + url?: string; + headers?: Record; +} + +const newSession = (opts: Options) => { + opts = Object.assign(defaultOptions, opts); + return { + get: async (path: string) => { + const res = await wrappedFetch( + opts.url + path, + { + headers: opts.headers, + }, + ); + if (res.status > 300) { + console.log(res); + throw new Error("Failed request, probably rate-limited"); + } + return res; + }, + post: async ( + path: string, + // deno-lint-ignore no-explicit-any + payload: any, + headers?: string, + ) => { + const res = await wrappedFetch( + opts.url + path, + { + "credentials": "include", + headers: Object.assign(headers ?? {}, opts.headers), + method: "POST", + body: payload, + }, + ); + if (res.status > 300) { + console.log(res); + throw new Error("Failed request, probably rate-limited"); + } + return res; + }, + }; +}; + +export { newSession }; diff --git a/tests/index.ts b/tests/index.ts index 0220179..463bd24 100644 --- a/tests/index.ts +++ b/tests/index.ts @@ -2,9 +2,11 @@ import AO3 from "../src/classes/AO3.ts"; import workTest from "./work.ts"; import chaptersTest from "./chapter.ts"; import searchTest from "./search.ts"; +import miscTest from "./misc.ts"; const ao3 = new AO3(); await workTest(ao3); await chaptersTest(ao3); await searchTest(ao3); +await miscTest(ao3); diff --git a/tests/misc.ts b/tests/misc.ts new file mode 100644 index 0000000..8f64ef4 --- /dev/null +++ b/tests/misc.ts @@ -0,0 +1,20 @@ +import AO3 from "../mod.ts"; +import { assert } from "https://deno.land/std@0.167.0/testing/asserts.ts"; + +export default function test(ao3: AO3) { + Deno.test("misc", async (test) => { + await test.step("alternate instances", async () => { + const ao3 = new AO3({ + url: "https://squidgeworld.org/", + }); + + const work = await ao3.getWork(34491); + await work.init(); + + assert( + work.name === "Implementing OTW's Code To Build SquidgeWorld", + "failed to get a work from alternate instance", + ); + }); + }); +}