first commit

This commit is contained in:
2026-04-09 13:05:27 +02:00
commit 3bbd7d6413
3084 changed files with 84284 additions and 0 deletions

View File

@@ -0,0 +1,15 @@
export interface FormDataEntry {
key: string;
value: string | Blob | Buffer;
fileName?: string;
}
export class FormData {
private _entries: FormDataEntry[] = [];
append(key: string, value: string | Blob | Buffer, fileName?: string): void {
this._entries.push({key, value, fileName});
}
}
export function getFormDataEntries(fd: FormData): FormDataEntry[] {
return (fd as any)._entries;
}

View File

@@ -0,0 +1,29 @@
import {Options as AsyncOptions} from 'then-request';
import {FormData, FormDataEntry} from './FormData';
export interface BaseOptions
extends Pick<
AsyncOptions,
| 'allowRedirectHeaders'
| 'followRedirects'
| 'gzip'
| 'headers'
| 'maxRedirects'
| 'maxRetries'
| 'qs'
| 'json'
> {
agent?: boolean;
cache?: 'file';
retry?: boolean;
retryDelay?: number;
socketTimeout?: number;
timeout?: number;
body?: string | Buffer;
}
export interface Options extends BaseOptions {
form?: FormData;
}
export interface MessageOptions extends BaseOptions {
form?: FormDataEntry[];
}

View File

@@ -0,0 +1,91 @@
import {URL} from 'url';
import {HttpVerb, Response} from 'then-request';
import handleQs from 'then-request/lib/handle-qs.js';
import {Options} from './Options';
import GenericResponse = require('http-response-object');
const fd = FormData as any;
export {fd as FormData};
export default function doRequest(
method: HttpVerb,
url: string | URL,
options?: Options
): Response {
var xhr = new XMLHttpRequest();
// check types of arguments
if (typeof method !== 'string') {
throw new TypeError('The method must be a string.');
}
if (url && typeof url === 'object') {
url = url.href;
}
if (typeof url !== 'string') {
throw new TypeError('The URL/path must be a string.');
}
if (options === null || options === undefined) {
options = {};
}
if (typeof options !== 'object') {
throw new TypeError('Options must be an object (or null).');
}
method = method.toUpperCase() as any;
options.headers = options.headers || {};
// handle cross domain
var match;
var crossDomain = !!(
(match = /^([\w-]+:)?\/\/([^\/]+)/.exec(url)) && match[2] != location.host
);
if (!crossDomain) options.headers['X-Requested-With'] = 'XMLHttpRequest';
// handle query string
if (options.qs) {
url = handleQs(url, options.qs);
}
// handle json body
if (options.json) {
options.body = JSON.stringify(options.json);
options.headers['content-type'] = 'application/json';
}
if (options.form) {
options.body = options.form as any;
}
// method, url, async
xhr.open(method, url, false);
for (var name in options.headers) {
xhr.setRequestHeader(name.toLowerCase(), '' + options.headers[name]);
}
// avoid sending empty string (#319)
xhr.send(options.body ? options.body : null);
var headers = {};
xhr
.getAllResponseHeaders()
.split('\r\n')
.forEach(function(header) {
var h = header.split(':');
if (h.length > 1) {
(headers as any)[h[0].toLowerCase()] = h
.slice(1)
.join(':')
.trim();
}
});
return new GenericResponse<string>(
xhr.status,
headers,
xhr.responseText,
url
);
}
module.exports = doRequest;
module.exports.default = doRequest;
module.exports.FormData = fd;

View File

@@ -0,0 +1,32 @@
import {HttpVerb, Response} from 'then-request';
import GenericResponse = require('http-response-object');
import {URL} from 'url';
import {Req, Res} from './messages';
import {FormData, getFormDataEntries} from './FormData';
import {Options, MessageOptions} from './Options';
const init = require('sync-rpc');
const remote = init(require.resolve('./worker'));
export {HttpVerb, Response, Options};
export {FormData};
export default function request(
method: HttpVerb,
url: string | URL,
options?: Options
): Response {
const {form, ...o} = options || {form: undefined};
const opts: MessageOptions = o;
if (form) {
opts.form = getFormDataEntries(form);
}
const req: Req = {
m: method,
u: url && typeof url === 'object' ? url.href : (url as string),
o: opts,
};
const res: Res = remote(req);
return new GenericResponse(res.s, res.h, res.b, res.u);
}
module.exports = request;
module.exports.default = request;
module.exports.FormData = FormData;

View File

@@ -0,0 +1,13 @@
import {Response, HttpVerb} from 'then-request';
import {MessageOptions} from './Options';
export type Req = {
m: HttpVerb;
u: string;
o?: MessageOptions;
};
export interface Res {
s: Response['statusCode'];
h: Response['headers'];
b: Response['body'];
u: Response['url'];
}

View File

@@ -0,0 +1,24 @@
import request, {Options, FormData} from 'then-request';
import {Req, Res} from './messages';
function init() {
return (req: Req): Promise<Res> => {
// Note how even though we return a promise, the resulting rpc client will be synchronous
const {form, ...o} = req.o || {form: undefined};
const opts: Options = o;
if (form) {
const fd = new FormData();
form.forEach(entry => {
fd.append(entry.key, entry.value, entry.fileName);
});
opts.form = fd;
}
return request(req.m, req.u, opts).then(response => ({
s: response.statusCode,
h: response.headers,
b: response.body,
u: response.url,
}));
};
}
module.exports = init;