- // ==UserScript==
- // @name GM Requests
- // @description Imitating Python's Requests library based on GM_xmlHttpRequest.
- // @version 0.0.2
- // @author 大碗宽面wtw
- // @homepage https://github.com/bigbowl-wtw/gm-requests/
- // @supportURL https://github.com/bigbowl-wtw/gm-requests/issues
- // @match *://*/*
- // @grant GM_xmlhttpRequest
- // @license MIT
- // @namespace com.github.bigbowl-wtw
- // ==/UserScript==
-
- (function webpackUniversalModuleDefinition(root, factory) {
- if (typeof exports === "object" && typeof module === "object") module.exports = factory(); else if (typeof define === "function" && define.amd) define([], factory); else if (typeof exports === "object") exports["requests"] = factory(); else root["requests"] = factory();
- })(self, (() => (() => {
- "use strict";
- var __webpack_require__ = {};
- (() => {
- __webpack_require__.d = (exports, definition) => {
- for (var key in definition) {
- if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
- Object.defineProperty(exports, key, {
- enumerable: true,
- get: definition[key]
- });
- }
- }
- };
- })();
- (() => {
- __webpack_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);
- })();
- (() => {
- __webpack_require__.r = exports => {
- if (typeof Symbol !== "undefined" && Symbol.toStringTag) {
- Object.defineProperty(exports, Symbol.toStringTag, {
- value: "Module"
- });
- }
- Object.defineProperty(exports, "__esModule", {
- value: true
- });
- };
- })();
- var __webpack_exports__ = {};
- __webpack_require__.r(__webpack_exports__);
- __webpack_require__.d(__webpack_exports__, {
- Session: () => Session,
- get: () => get,
- post: () => post,
- session: () => session
- });
- var ErrorStatus;
- (function(ErrorStatus) {
- ErrorStatus[ErrorStatus["BadRequest"] = 400] = "BadRequest";
- ErrorStatus[ErrorStatus["Unauthorized"] = 401] = "Unauthorized";
- ErrorStatus[ErrorStatus["Forbidden"] = 403] = "Forbidden";
- ErrorStatus[ErrorStatus["NotFound"] = 404] = "NotFound";
- ErrorStatus[ErrorStatus["MethodNotAllowed"] = 405] = "MethodNotAllowed";
- ErrorStatus[ErrorStatus["RequestTimeout"] = 408] = "RequestTimeout";
- ErrorStatus[ErrorStatus["TooManyRequests"] = 429] = "TooManyRequests";
- ErrorStatus[ErrorStatus["InternalServerError"] = 500] = "InternalServerError";
- ErrorStatus[ErrorStatus["BadGateway"] = 502] = "BadGateway";
- ErrorStatus[ErrorStatus["ServiceUnavailable"] = 503] = "ServiceUnavailable";
- })(ErrorStatus || (ErrorStatus = {}));
- function utils_assign(target, ...rest) {
- const __assign = Object.assign || function(t, ...others) {
- for (let s, i = 0, n = others.length; i < n; i++) {
- s = others[i];
- for (const p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
- }
- return t;
- };
- return __assign.call(this, target, ...rest);
- }
- function assignDeepCopy(target, ...rest) {
- rest = rest.filter((r => r !== undefined));
- utils_assign(target, ...rest);
- return utils_assign.call(this, target, ...JSON.parse(JSON.stringify(rest)));
- }
- function bodyToString(data) {
- if (Object.values(data).some((v => typeof v.toString !== "function"))) throw new TypeError("value must has `.toString`");
- return Object.entries(data).map((([key, value]) => `${key}=${encodeURIComponent(value.toString())}`)).join("&");
- }
- class SimpleCookieJar {
- get empty() {
- return !Object.keys(this.cookies).length;
- }
- constructor(cookies) {
- var _a;
- this.never = new Set;
- this.setCookies((_a = cookies) !== null && _a !== void 0 ? _a : {});
- }
- update(cookies) {
- utils_assign(this.cookies, this.normalizeCookie(cookies));
- }
- updateFromString(cookieStringArray) {
- if (typeof cookieStringArray === "string") cookieStringArray = [ cookieStringArray ];
- this.update(cookieStringArray);
- }
- differenceUpdate(cookies) {
- let cookieEntries;
- if (Array.isArray(cookies)) cookieEntries = cookies.map(this.stringToEntry); else cookieEntries = Object.entries(isCookieJar(cookies) ? cookies.cookies : cookies);
- const set = new Set(Object.keys(this.cookies));
- cookieEntries = cookieEntries.filter((([name]) => !set.has(name)));
- this.update(Object.fromEntries(cookieEntries));
- }
- deleteFromString(cookieStringArray) {
- if (typeof cookieStringArray === "string") cookieStringArray = [ cookieStringArray ];
- const names = cookieStringArray.map(this.stringToEntry).map((([name]) => name));
- names.forEach((name => {
- this.never.add(name);
- delete this.cookies[name];
- }));
- }
- setCookies(cookies) {
- this.cookies = new Proxy(this.normalizeCookie(cookies), {
- set: (target, name, value) => {
- if (this.never.has(name)) return true;
- target[name] = value;
- return true;
- }
- });
- }
- toString() {
- return Object.entries(this.cookies).map((([k, v]) => `${k}=${v}`)).join(";");
- }
- parseCookieString(cookieStrings) {
- return Object.fromEntries(cookieStrings.map(this.stringToEntry));
- }
- normalizeCookie(cookies) {
- if (Array.isArray(cookies)) return this.parseCookieString(cookies);
- if (isCookieJar(cookies)) return cookies.cookies;
- return cookies;
- }
- stringToEntry(cookieString) {
- return cookieString.slice(0, cookieString.indexOf(";")).split("=");
- }
- }
- function isCookieJar(obj) {
- return typeof obj.update === "function";
- }
- var __rest = undefined && undefined.__rest || function(s, e) {
- var t = {};
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
- if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
- }
- return t;
- };
- class Header {
- constructor(headers) {
- this.cookies = new SimpleCookieJar;
- if (!headers) {
- this.headers = {};
- return;
- }
- const {cookie} = headers, others = __rest(headers, [ "cookie" ]);
- this.headers = others;
- if (cookie) {
- this.cookies.update(cookie);
- }
- }
- setFromString(headerString) {
- const entrise = headerString.split("\r\n").map((kv => kv.split(":"))).map((([k, v]) => [ k.toLowerCase(), v.trim() ]));
- for (const [name, value] of entrise) {
- const header = this.headers[name];
- if (header) {
- if (typeof header === "string") this.headers[name] = [ header ];
- this.headers[name].push(value);
- } else {
- this.headers[name] = value;
- }
- }
- return this;
- }
- update(headers) {
- if (isIHeader(headers)) {
- this.cookies.update(headers.cookies);
- this.update(headers.headers);
- } else {
- const _a = headers !== null && headers !== void 0 ? headers : {}, {cookie} = _a, others = __rest(_a, [ "cookie" ]);
- utils_assign(this.headers, others);
- if (cookie) {
- this.cookies.update(cookie);
- }
- }
- }
- getHeaders() {
- if (!Object.keys(this.headers).length) {
- if (this.cookies.empty) return {};
- return {
- cookie: this.cookies.toString()
- };
- }
- const headers = {};
- for (const [name, value] of Object.entries(this.headers)) headers[name] = value.toString();
- return Object.assign(Object.assign({}, headers), {
- cookie: this.cookies.toString()
- });
- }
- append(header, value) {
- if (header === "cookie") this.cookies.update([ header ]); else if (!this[header]) this[header] = value; else if (!Array.isArray(header)) this[header] = [ value ].concat(this[header]); else this[header].concat(value);
- }
- get(name) {
- return this.headers[name];
- }
- }
- function isIHeader(obj) {
- return typeof obj.update === "function";
- }
- var __awaiter = undefined && undefined.__awaiter || function(thisArg, _arguments, P, generator) {
- function adopt(value) {
- return value instanceof P ? value : new P((function(resolve) {
- resolve(value);
- }));
- }
- return new (P || (P = Promise))((function(resolve, reject) {
- function fulfilled(value) {
- try {
- step(generator.next(value));
- } catch (e) {
- reject(e);
- }
- }
- function rejected(value) {
- try {
- step(generator["throw"](value));
- } catch (e) {
- reject(e);
- }
- }
- function step(result) {
- result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
- }
- step((generator = generator.apply(thisArg, _arguments || [])).next());
- }));
- };
- var session_rest = undefined && undefined.__rest || function(s, e) {
- var t = {};
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
- if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
- }
- return t;
- };
- class Details {
- constructor(url, method, options) {
- this.pendings = [];
- this.url = url;
- this.method = method;
- this.finalHeader = new Header;
- if (options) {
- const {query, json, data, cookie, auth, headers} = options, others = session_rest(options, [ "query", "json", "data", "cookie", "auth", "headers" ]);
- this.query = query;
- this.json = json;
- this.data = data;
- this.cookie = cookie;
- this.auth = auth;
- this.headers = headers;
- this.others = others;
- }
- }
- build(session) {
- return __awaiter(this, void 0, void 0, (function*() {
- this.buildURL().buildHeaderAndCookie(session).buildAuth(session);
- this.pendings.concat(session.buildHooks.map((hook => hook.call(this, session))));
- return this.toDetails();
- }));
- }
- buildURL() {
- this.parseQuery(this.query);
- return this;
- }
- buildHeaderAndCookie(session) {
- const finalCookie = this.finalHeader.cookies;
- if (!session.cookies.empty) finalCookie.update(session.cookies);
- if (this.cookie) finalCookie.update(this.cookie);
- this.finalHeader.update(session.headers);
- if (this.headers) this.finalHeader.update(this.headers);
- return this;
- }
- buildAuth(session) {
- var _a;
- this.pendings.push((_a = session.auth) === null || _a === void 0 ? void 0 : _a.build(this.finalHeader));
- return this;
- }
- buildBody() {
- if (this.json) {
- const contentType = "application/json";
- this.finalHeader.update({
- "Content-Type": contentType
- });
- const data = JSON.stringify(this.json);
- this.finalData = data;
- return this;
- }
- if (this.data) {
- if (typeof this.data === "string") {
- this.finalData = this.data;
- return this;
- }
- if (this.data instanceof FormData) return this;
- const contentType = "application/x-www-form-urlencoded";
- this.finalHeader.update({
- "Content-Type": contentType
- });
- this.finalData = bodyToString(this.data);
- return this;
- }
- return this;
- }
- toDetails() {
- return __awaiter(this, void 0, void 0, (function*() {
- yield Promise.all(this.pendings);
- const url = this.url.toString();
- this.buildBody();
- const details = Object.assign({
- url,
- method: this.method,
- headers: this.finalHeader.getHeaders()
- }, this.others);
- if (this.finalData) details.data = this.finalData;
- return details;
- }));
- }
- parseQuery(query) {
- let url;
- if (typeof this.url === "string") url = new URL(this.url); else url = this.url;
- if (query) Object.entries(query).filter((([_, v]) => typeof v === "string")).forEach((([k, v]) => url.searchParams.append(k, v.toString())));
- this.url = url;
- }
- }
- class Session {
- constructor() {
- this.buildHooks = [];
- const headers = new Header;
- Object.defineProperty(this, "headers", {
- get: () => headers,
- set(value) {
- headers.update(value);
- }
- });
- Object.defineProperty(this, "cookies", {
- get: () => headers.cookies,
- set(value) {
- headers.cookies.setCookies(value);
- }
- });
- }
- get(url, options) {
- return __awaiter(this, void 0, void 0, (function*() {
- return this.request("GET", url, options);
- }));
- }
- post(url, options) {
- return __awaiter(this, void 0, void 0, (function*() {
- return this.request("POST", url, options);
- }));
- }
- request(method, url, options) {
- return __awaiter(this, void 0, void 0, (function*() {
- const details = new Details(url, method, options);
- return new Promise(((resolve, reject) => {
- if (!options.onload) {
- details.others.onload = resp => {
- if (!this.cookies.empty) {
- const respHeaders = (new Header).setFromString(resp.responseHeaders);
- this.cookies.deleteFromString(respHeaders["set-cookie"]);
- }
- if (resp.status === 200 && !(resp.status in ErrorStatus)) resolve((options === null || options === void 0 ? void 0 : options.responseType) ? resp.response : resp); else reject(resp);
- };
- }
- if (!options.onerror) details.others.onerror = resp => reject(resp);
- details.build(this).then((dtl => GM_xmlhttpRequest(dtl)));
- }));
- }));
- }
- registerBuildHook(hook) {
- this.buildHooks.push(hook);
- }
- }
- function get(url, query, options) {
- return (new Session).get(url, Object.assign({
- query
- }, options));
- }
- function post(url, options) {
- return (new Session).post(url, Object.assign({}, options));
- }
- function session() {
- return new Session;
- }
- return __webpack_exports__;
- })()));