🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

teleman

Package Overview
Dependencies
Maintainers
1
Versions
39
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

teleman - npm Package Compare versions

Comparing version
0.7.4
to
0.8.0
+7
.prettierrc
{
"semi": false,
"singleQuote": true,
"trailingComma": "none",
"arrowParens": "avoid",
"experimentalTernaries": true
}
+36
-34

@@ -11,3 +11,3 @@ 'use strict';

}
if (Object.prototype.toString.call(query) === "[object Object]") {
if (Object.prototype.toString.call(query) === '[object Object]') {
query = Object.entries(query);

@@ -24,3 +24,3 @@ }

function createFormData(data) {
if (Object.prototype.toString.call(data) === "[object Object]") {
if (Object.prototype.toString.call(data) === '[object Object]') {
data = Object.entries(data);

@@ -45,3 +45,3 @@ }

middleware = [];
constructor({ base, headers, } = {}) {
constructor({ base, headers } = {}) {
if (base) {

@@ -65,3 +65,3 @@ this.base = base;

}
async fetch(path, { method = "GET", base = this.base, headers, query, params = {}, body, use = this.middleware, ...rest } = {}) {
async fetch(path, { method = 'GET', base = this.base, headers, query, params = {}, body, use = this.middleware, ...rest } = {}) {
method = method.toUpperCase();

@@ -85,14 +85,14 @@ const url = new URL(path.replace(/:([a-z]\w*)/gi, (_, w) => encodeURIComponent(params[w])), base);

body !== null &&
!["GET", "HEAD"].includes(method)) {
const contentType = headers.get("content-type") || "";
!['GET', 'HEAD'].includes(method)) {
const contentType = headers.get('content-type') || '';
if ((!contentType &&
body &&
Object.prototype.toString.call(body) === "[object Object]") ||
contentType.startsWith("application/json")) {
if (!headers.has("content-type")) {
headers.set("content-type", "application/json");
Object.prototype.toString.call(body) === '[object Object]') ||
contentType.startsWith('application/json')) {
if (!headers.has('content-type')) {
headers.set('content-type', 'application/json');
}
body = JSON.stringify(body);
}
else if (contentType.startsWith("multipart/form-data") &&
else if (contentType.startsWith('multipart/form-data') &&
body &&

@@ -102,3 +102,3 @@ !(body instanceof FormData)) {

}
else if (contentType.startsWith("application/x-www-form-urlencoded") &&
else if (contentType.startsWith('application/x-www-form-urlencoded') &&
body &&

@@ -114,16 +114,16 @@ !(body instanceof URLSearchParams)) {

headers,
body: body,
body: body
},
...rest,
...rest
};
return compose(use)(ctx, () => fetch(ctx.url.href, ctx.options).then((response) => {
return compose(use)(ctx, () => fetch(ctx.url.href, ctx.options).then(response => {
ctx.response = response;
let body = Promise.resolve(response);
if (!["HEAD", "head"].includes(ctx.options.method)) {
const responseType = response.headers.get("content-type");
if (!['HEAD', 'head'].includes(ctx.options.method)) {
const responseType = response.headers.get('content-type');
if (responseType) {
if (responseType.startsWith("application/json")) {
if (responseType.startsWith('application/json')) {
body = response.json();
}
else if (responseType.startsWith("text/")) {
else if (responseType.startsWith('text/')) {
body = response.text();

@@ -137,3 +137,3 @@ }

else {
return body.then((e) => {
return body.then(e => {
throw e;

@@ -147,4 +147,4 @@ });

...options,
method: "GET",
query,
method: 'GET',
query
});

@@ -155,4 +155,4 @@ }

...options,
method: "POST",
body,
method: 'POST',
body
});

@@ -163,4 +163,4 @@ }

...options,
method: "PUT",
body,
method: 'PUT',
body
});

@@ -171,4 +171,4 @@ }

...options,
method: "PATCH",
body,
method: 'PATCH',
body
});

@@ -179,4 +179,4 @@ }

...options,
method: "DELETE",
query,
method: 'DELETE',
query
});

@@ -187,4 +187,4 @@ }

...options,
method: "HEAD",
query,
method: 'HEAD',
query
});

@@ -195,4 +195,4 @@ }

...options,
method: "PURGE",
query,
method: 'PURGE',
query
});

@@ -204,4 +204,6 @@ }

exports.Teleman = Teleman;
exports.createFormData = createFormData;
exports.createURLSearchParams = createURLSearchParams;
exports.default = Teleman;
exports.teleman = teleman;
//# sourceMappingURL=index.cjs.map

@@ -1,1 +0,1 @@

{"version":3,"file":"index.cjs","sources":["../src/index.ts"],"sourcesContent":["import compose from \"koa-compose\";\nfunction createURLSearchParams(query) {\n if (query.constructor === String) {\n return new URLSearchParams(query);\n }\n if (Object.prototype.toString.call(query) === \"[object Object]\") {\n query = Object.entries(query);\n }\n const q = new URLSearchParams();\n for (const [name, value] of query) {\n if (value !== null && value !== undefined) {\n q.append(name, value);\n }\n }\n return q;\n}\nfunction createFormData(data) {\n if (Object.prototype.toString.call(data) === \"[object Object]\") {\n data = Object.entries(data);\n }\n const f = new FormData();\n for (const [name, value, filename] of data) {\n if (value !== null && value !== undefined) {\n if (filename) {\n f.append(name, value, filename);\n }\n else {\n f.append(name, value);\n }\n }\n }\n return f;\n}\nclass Teleman {\n base;\n headers;\n middleware = [];\n constructor({ base, headers, } = {}) {\n if (base) {\n this.base = base;\n }\n else {\n try {\n // defaults to document.baseURI in browser\n this.base = document.baseURI;\n }\n catch (e) {\n // in node.js, ignore\n }\n }\n this.headers = new Headers(headers);\n }\n use(middleware) {\n this.middleware.push(middleware);\n return this;\n }\n async fetch(path, { method = \"GET\", base = this.base, headers, query, params = {}, body, use = this.middleware, ...rest } = {}) {\n method = method.toUpperCase();\n const url = new URL(path.replace(/:([a-z]\\w*)/gi, (_, w) => encodeURIComponent(params[w])), base);\n if (query) {\n if (!(query instanceof URLSearchParams)) {\n query = createURLSearchParams(query);\n }\n query.forEach((value, name) => url.searchParams.append(name, value));\n }\n if (this.headers && headers) {\n const h = new Headers(this.headers);\n new Headers(headers).forEach((value, name) => h.set(name, value));\n headers = h;\n }\n else {\n headers = new Headers(this.headers || headers);\n }\n if (body !== undefined &&\n body !== null &&\n ![\"GET\", \"HEAD\"].includes(method)) {\n const contentType = headers.get(\"content-type\") || \"\";\n if ((!contentType &&\n body &&\n Object.prototype.toString.call(body) === \"[object Object]\") ||\n contentType.startsWith(\"application/json\")) {\n if (!headers.has(\"content-type\")) {\n headers.set(\"content-type\", \"application/json\");\n }\n body = JSON.stringify(body);\n }\n else if (contentType.startsWith(\"multipart/form-data\") &&\n body &&\n !(body instanceof FormData)) {\n body = createFormData(body);\n }\n else if (contentType.startsWith(\"application/x-www-form-urlencoded\") &&\n body &&\n !(body instanceof URLSearchParams)) {\n body = createURLSearchParams(body);\n }\n }\n const ctx = {\n url,\n options: {\n method,\n headers,\n body: body,\n },\n ...rest,\n };\n return compose(use)(ctx, () => fetch(ctx.url.href, ctx.options).then((response) => {\n ctx.response = response;\n let body = Promise.resolve(response);\n if (![\"HEAD\", \"head\"].includes(ctx.options.method)) {\n const responseType = response.headers.get(\"content-type\");\n if (responseType) {\n if (responseType.startsWith(\"application/json\")) {\n body = response.json();\n }\n else if (responseType.startsWith(\"text/\")) {\n body = response.text();\n }\n }\n }\n if (response.ok) {\n return body;\n }\n else {\n return body.then((e) => {\n throw e;\n });\n }\n }));\n }\n get(path, query, options) {\n return this.fetch(path, {\n ...options,\n method: \"GET\",\n query,\n });\n }\n post(path, body, options) {\n return this.fetch(path, {\n ...options,\n method: \"POST\",\n body,\n });\n }\n put(path, body, options) {\n return this.fetch(path, {\n ...options,\n method: \"PUT\",\n body,\n });\n }\n patch(path, body, options) {\n return this.fetch(path, {\n ...options,\n method: \"PATCH\",\n body,\n });\n }\n delete(path, query, options) {\n return this.fetch(path, {\n ...options,\n method: \"DELETE\",\n query,\n });\n }\n head(path, query, options) {\n return this.fetch(path, {\n ...options,\n method: \"HEAD\",\n query,\n });\n }\n purge(path, query, options) {\n return this.fetch(path, {\n ...options,\n method: \"PURGE\",\n query,\n });\n }\n}\nexport default Teleman;\nexport { Teleman };\nexport const teleman = new Teleman();\n//# sourceMappingURL=index.js.map"],"names":[],"mappings":"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"}
{"version":3,"file":"index.cjs","sources":["../src/index.ts"],"sourcesContent":["import compose from 'koa-compose'\n\nexport type PrimitiveType = string | number | boolean | null | undefined\n\nexport type SerializableData =\n | string\n | number\n | boolean\n | null\n | undefined\n | SerializableData[]\n | { [name: string]: SerializableData }\n\nexport type ReqOptions = {\n method?: Method | MethodLowercase\n base?: string\n headers?: Headers | Record<string, string>\n query?:\n | URLSearchParams\n | string\n | Record<string, PrimitiveType>\n | [string, PrimitiveType][]\n params?: Record<string, string | number | boolean>\n body?: ReqBody | SerializableData\n use?: Middleware[]\n [index: string]: unknown\n}\n\nexport type Method =\n | 'GET'\n | 'POST'\n | 'PUT'\n | 'DELETE'\n | 'PATCH'\n | 'HEAD'\n | 'PURGE'\nexport type MethodLowercase =\n | 'get'\n | 'post'\n | 'put'\n | 'delete'\n | 'patch'\n | 'head'\n | 'purge'\nexport type ReqBody =\n | string\n | FormData\n | URLSearchParams\n | Blob\n | BufferSource\n | ReadableStream\n\nexport type MiddlewareCtx = {\n url: URL\n\n options: {\n method: Method\n headers: Headers\n body: ReqBody\n }\n\n response?: Response\n [name: string]: unknown\n}\n\nexport type Middleware = (\n ctx: MiddlewareCtx,\n next: () => Promise<any> // eslint-disable-line @typescript-eslint/no-explicit-any\n) => unknown\nexport type Query =\n | string\n | Record<string, PrimitiveType>\n | [string, PrimitiveType][]\nexport type FormBody =\n | Record<string, PrimitiveType | Blob>\n | [string, PrimitiveType | Blob, string?][]\n\nexport function createURLSearchParams(query: Query) {\n if (query.constructor === String) {\n return new URLSearchParams(query)\n }\n\n if (Object.prototype.toString.call(query) === '[object Object]') {\n query = Object.entries(query)\n }\n\n const q = new URLSearchParams()\n\n for (const [name, value] of query as [string, PrimitiveType][]) {\n if (value !== null && value !== undefined) {\n q.append(name, value as string)\n }\n }\n\n return q\n}\n\nexport function createFormData(data: FormBody) {\n if (Object.prototype.toString.call(data) === '[object Object]') {\n data = Object.entries(data)\n }\n\n const f = new FormData()\n\n for (const [name, value, filename] of data as [\n string,\n PrimitiveType | Blob,\n string?\n ][]) {\n if (value !== null && value !== undefined) {\n if (filename) {\n f.append(name, value as Blob, filename)\n } else {\n f.append(name, value as string)\n }\n }\n }\n\n return f\n}\n\nclass Teleman {\n base?: string\n headers: Headers\n middleware: Middleware[] = []\n\n constructor({\n base,\n headers\n }: {\n base?: string\n headers?: Headers | Record<string, string>\n } = {}) {\n if (base) {\n this.base = base\n } else {\n try {\n // defaults to document.baseURI in browser\n this.base = document.baseURI\n } catch (e) {\n // in node.js, ignore\n }\n }\n\n this.headers = new Headers(headers)\n }\n\n use(middleware: Middleware) {\n this.middleware.push(middleware)\n return this\n }\n\n async fetch<T>(\n path: string,\n {\n method = 'GET',\n base = this.base,\n headers,\n query,\n params = {},\n body,\n use = this.middleware,\n ...rest\n }: ReqOptions = {}\n ): Promise<T> {\n method = method.toUpperCase() as Method\n const url = new URL(\n path.replace(/:([a-z]\\w*)/gi, (_, w) => encodeURIComponent(params[w])),\n base\n )\n\n if (query) {\n if (!(query instanceof URLSearchParams)) {\n query = createURLSearchParams(query)\n }\n\n query.forEach((value, name) => url.searchParams.append(name, value))\n }\n\n if (this.headers && headers) {\n const h = new Headers(this.headers)\n new Headers(headers).forEach((value, name) => h.set(name, value))\n headers = h\n } else {\n headers = new Headers(this.headers || headers)\n }\n\n if (\n body !== undefined &&\n body !== null &&\n !['GET', 'HEAD'].includes(method)\n ) {\n const contentType = headers.get('content-type') || ''\n\n if (\n (!contentType &&\n body &&\n Object.prototype.toString.call(body) === '[object Object]') ||\n contentType.startsWith('application/json')\n ) {\n if (!headers.has('content-type')) {\n headers.set('content-type', 'application/json')\n }\n\n body = JSON.stringify(body)\n } else if (\n contentType.startsWith('multipart/form-data') &&\n body &&\n !(body instanceof FormData)\n ) {\n body = createFormData(body as FormBody)\n } else if (\n contentType.startsWith('application/x-www-form-urlencoded') &&\n body &&\n !(body instanceof URLSearchParams)\n ) {\n body = createURLSearchParams(body as Query)\n }\n }\n\n const ctx: MiddlewareCtx = {\n url,\n\n options: {\n method,\n headers,\n body: body as ReqBody\n },\n\n ...rest\n }\n\n return <Promise<T>>compose(use)(ctx, () =>\n fetch(ctx.url.href, ctx.options).then(response => {\n ctx.response = response\n let body: Promise<unknown> = Promise.resolve(response)\n\n if (!['HEAD', 'head'].includes(ctx.options.method)) {\n const responseType = response.headers.get('content-type')\n\n if (responseType) {\n if (responseType.startsWith('application/json')) {\n body = response.json()\n } else if (responseType.startsWith('text/')) {\n body = response.text()\n }\n }\n }\n\n if (response.ok) {\n return body\n } else {\n return body.then(e => {\n throw e\n })\n }\n })\n )\n }\n\n get<T>(path: string, query?: Query, options?: ReqOptions) {\n return this.fetch<T>(path, {\n ...options,\n method: 'GET',\n query\n })\n }\n\n post<T>(\n path: string,\n body?: ReqBody | SerializableData,\n options?: ReqOptions\n ) {\n return this.fetch<T>(path, {\n ...options,\n method: 'POST',\n body\n })\n }\n\n put<T>(\n path: string,\n body?: ReqBody | SerializableData,\n options?: ReqOptions\n ) {\n return this.fetch<T>(path, {\n ...options,\n method: 'PUT',\n body\n })\n }\n\n patch<T>(\n path: string,\n body?: ReqBody | SerializableData,\n options?: ReqOptions\n ) {\n return this.fetch<T>(path, {\n ...options,\n method: 'PATCH',\n body\n })\n }\n\n delete<T>(path: string, query?: Query, options?: ReqOptions) {\n return this.fetch<T>(path, {\n ...options,\n method: 'DELETE',\n query\n })\n }\n\n head<T>(path: string, query?: Query, options?: ReqOptions) {\n return this.fetch<T>(path, {\n ...options,\n method: 'HEAD',\n query\n })\n }\n\n purge<T>(path: string, query?: Query, options?: ReqOptions) {\n return this.fetch<T>(path, {\n ...options,\n method: 'PURGE',\n query\n })\n }\n}\n\nexport default Teleman\nexport { Teleman }\nexport const teleman = new Teleman()\n"],"names":[],"mappings":"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"}

@@ -15,4 +15,4 @@ export type PrimitiveType = string | number | boolean | null | undefined;

};
export type Method = "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "HEAD" | "PURGE";
export type MethodLowercase = "get" | "post" | "put" | "delete" | "patch" | "head" | "purge";
export type Method = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'PURGE';
export type MethodLowercase = 'get' | 'post' | 'put' | 'delete' | 'patch' | 'head' | 'purge';
export type ReqBody = string | FormData | URLSearchParams | Blob | BufferSource | ReadableStream;

@@ -32,2 +32,4 @@ export type MiddlewareCtx = {

export type FormBody = Record<string, PrimitiveType | Blob> | [string, PrimitiveType | Blob, string?][];
export declare function createURLSearchParams(query: Query): URLSearchParams;
export declare function createFormData(data: FormBody): FormData;
declare class Teleman {

@@ -37,3 +39,3 @@ base?: string;

middleware: Middleware[];
constructor({ base, headers, }?: {
constructor({ base, headers }?: {
base?: string;

@@ -40,0 +42,0 @@ headers?: Headers | Record<string, string>;

@@ -5,50 +5,60 @@ function getDefaultExportFromCjs (x) {

/**
* Expose compositor.
*/
var koaCompose;
var hasRequiredKoaCompose;
var koaCompose = compose;
function requireKoaCompose () {
if (hasRequiredKoaCompose) return koaCompose;
hasRequiredKoaCompose = 1;
/**
* Compose `middleware` returning
* a fully valid middleware comprised
* of all those which are passed.
*
* @param {Array} middleware
* @return {Function}
* @api public
*/
/**
* Expose compositor.
*/
function compose (middleware) {
if (!Array.isArray(middleware)) throw new TypeError('Middleware stack must be an array!')
for (const fn of middleware) {
if (typeof fn !== 'function') throw new TypeError('Middleware must be composed of functions!')
}
koaCompose = compose;
/**
* @param {Object} context
* @return {Promise}
* @api public
*/
/**
* Compose `middleware` returning
* a fully valid middleware comprised
* of all those which are passed.
*
* @param {Array} middleware
* @return {Function}
* @api public
*/
return function (context, next) {
// last called middleware #
let index = -1;
return dispatch(0)
function dispatch (i) {
if (i <= index) return Promise.reject(new Error('next() called multiple times'))
index = i;
let fn = middleware[i];
if (i === middleware.length) fn = next;
if (!fn) return Promise.resolve()
try {
return Promise.resolve(fn(context, dispatch.bind(null, i + 1)));
} catch (err) {
return Promise.reject(err)
}
}
}
function compose (middleware) {
if (!Array.isArray(middleware)) throw new TypeError('Middleware stack must be an array!')
for (const fn of middleware) {
if (typeof fn !== 'function') throw new TypeError('Middleware must be composed of functions!')
}
/**
* @param {Object} context
* @return {Promise}
* @api public
*/
return function (context, next) {
// last called middleware #
let index = -1;
return dispatch(0)
function dispatch (i) {
if (i <= index) return Promise.reject(new Error('next() called multiple times'))
index = i;
let fn = middleware[i];
if (i === middleware.length) fn = next;
if (!fn) return Promise.resolve()
try {
return Promise.resolve(fn(context, dispatch.bind(null, i + 1)));
} catch (err) {
return Promise.reject(err)
}
}
}
}
return koaCompose;
}
var compose$1 = /*@__PURE__*/getDefaultExportFromCjs(koaCompose);
var koaComposeExports = requireKoaCompose();
var compose = /*@__PURE__*/getDefaultExportFromCjs(koaComposeExports);

@@ -59,3 +69,3 @@ function createURLSearchParams(query) {

}
if (Object.prototype.toString.call(query) === "[object Object]") {
if (Object.prototype.toString.call(query) === '[object Object]') {
query = Object.entries(query);

@@ -72,3 +82,3 @@ }

function createFormData(data) {
if (Object.prototype.toString.call(data) === "[object Object]") {
if (Object.prototype.toString.call(data) === '[object Object]') {
data = Object.entries(data);

@@ -93,3 +103,3 @@ }

middleware = [];
constructor({ base, headers, } = {}) {
constructor({ base, headers } = {}) {
if (base) {

@@ -113,3 +123,3 @@ this.base = base;

}
async fetch(path, { method = "GET", base = this.base, headers, query, params = {}, body, use = this.middleware, ...rest } = {}) {
async fetch(path, { method = 'GET', base = this.base, headers, query, params = {}, body, use = this.middleware, ...rest } = {}) {
method = method.toUpperCase();

@@ -133,14 +143,14 @@ const url = new URL(path.replace(/:([a-z]\w*)/gi, (_, w) => encodeURIComponent(params[w])), base);

body !== null &&
!["GET", "HEAD"].includes(method)) {
const contentType = headers.get("content-type") || "";
!['GET', 'HEAD'].includes(method)) {
const contentType = headers.get('content-type') || '';
if ((!contentType &&
body &&
Object.prototype.toString.call(body) === "[object Object]") ||
contentType.startsWith("application/json")) {
if (!headers.has("content-type")) {
headers.set("content-type", "application/json");
Object.prototype.toString.call(body) === '[object Object]') ||
contentType.startsWith('application/json')) {
if (!headers.has('content-type')) {
headers.set('content-type', 'application/json');
}
body = JSON.stringify(body);
}
else if (contentType.startsWith("multipart/form-data") &&
else if (contentType.startsWith('multipart/form-data') &&
body &&

@@ -150,3 +160,3 @@ !(body instanceof FormData)) {

}
else if (contentType.startsWith("application/x-www-form-urlencoded") &&
else if (contentType.startsWith('application/x-www-form-urlencoded') &&
body &&

@@ -162,16 +172,16 @@ !(body instanceof URLSearchParams)) {

headers,
body: body,
body: body
},
...rest,
...rest
};
return compose$1(use)(ctx, () => fetch(ctx.url.href, ctx.options).then((response) => {
return compose(use)(ctx, () => fetch(ctx.url.href, ctx.options).then(response => {
ctx.response = response;
let body = Promise.resolve(response);
if (!["HEAD", "head"].includes(ctx.options.method)) {
const responseType = response.headers.get("content-type");
if (!['HEAD', 'head'].includes(ctx.options.method)) {
const responseType = response.headers.get('content-type');
if (responseType) {
if (responseType.startsWith("application/json")) {
if (responseType.startsWith('application/json')) {
body = response.json();
}
else if (responseType.startsWith("text/")) {
else if (responseType.startsWith('text/')) {
body = response.text();

@@ -185,3 +195,3 @@ }

else {
return body.then((e) => {
return body.then(e => {
throw e;

@@ -195,4 +205,4 @@ });

...options,
method: "GET",
query,
method: 'GET',
query
});

@@ -203,4 +213,4 @@ }

...options,
method: "POST",
body,
method: 'POST',
body
});

@@ -211,4 +221,4 @@ }

...options,
method: "PUT",
body,
method: 'PUT',
body
});

@@ -219,4 +229,4 @@ }

...options,
method: "PATCH",
body,
method: 'PATCH',
body
});

@@ -227,4 +237,4 @@ }

...options,
method: "DELETE",
query,
method: 'DELETE',
query
});

@@ -235,4 +245,4 @@ }

...options,
method: "HEAD",
query,
method: 'HEAD',
query
});

@@ -243,4 +253,4 @@ }

...options,
method: "PURGE",
query,
method: 'PURGE',
query
});

@@ -251,3 +261,3 @@ }

export { Teleman, Teleman as default, teleman };
export { Teleman, createFormData, createURLSearchParams, Teleman as default, teleman };
//# sourceMappingURL=index.js.map

@@ -1,1 +0,1 @@

{"version":3,"file":"index.js","sources":["../node_modules/.pnpm/koa-compose@4.1.0/node_modules/koa-compose/index.js","../src/index.ts"],"sourcesContent":["'use strict'\n\n/**\n * Expose compositor.\n */\n\nmodule.exports = compose\n\n/**\n * Compose `middleware` returning\n * a fully valid middleware comprised\n * of all those which are passed.\n *\n * @param {Array} middleware\n * @return {Function}\n * @api public\n */\n\nfunction compose (middleware) {\n if (!Array.isArray(middleware)) throw new TypeError('Middleware stack must be an array!')\n for (const fn of middleware) {\n if (typeof fn !== 'function') throw new TypeError('Middleware must be composed of functions!')\n }\n\n /**\n * @param {Object} context\n * @return {Promise}\n * @api public\n */\n\n return function (context, next) {\n // last called middleware #\n let index = -1\n return dispatch(0)\n function dispatch (i) {\n if (i <= index) return Promise.reject(new Error('next() called multiple times'))\n index = i\n let fn = middleware[i]\n if (i === middleware.length) fn = next\n if (!fn) return Promise.resolve()\n try {\n return Promise.resolve(fn(context, dispatch.bind(null, i + 1)));\n } catch (err) {\n return Promise.reject(err)\n }\n }\n }\n}\n","import compose from \"koa-compose\";\nfunction createURLSearchParams(query) {\n if (query.constructor === String) {\n return new URLSearchParams(query);\n }\n if (Object.prototype.toString.call(query) === \"[object Object]\") {\n query = Object.entries(query);\n }\n const q = new URLSearchParams();\n for (const [name, value] of query) {\n if (value !== null && value !== undefined) {\n q.append(name, value);\n }\n }\n return q;\n}\nfunction createFormData(data) {\n if (Object.prototype.toString.call(data) === \"[object Object]\") {\n data = Object.entries(data);\n }\n const f = new FormData();\n for (const [name, value, filename] of data) {\n if (value !== null && value !== undefined) {\n if (filename) {\n f.append(name, value, filename);\n }\n else {\n f.append(name, value);\n }\n }\n }\n return f;\n}\nclass Teleman {\n base;\n headers;\n middleware = [];\n constructor({ base, headers, } = {}) {\n if (base) {\n this.base = base;\n }\n else {\n try {\n // defaults to document.baseURI in browser\n this.base = document.baseURI;\n }\n catch (e) {\n // in node.js, ignore\n }\n }\n this.headers = new Headers(headers);\n }\n use(middleware) {\n this.middleware.push(middleware);\n return this;\n }\n async fetch(path, { method = \"GET\", base = this.base, headers, query, params = {}, body, use = this.middleware, ...rest } = {}) {\n method = method.toUpperCase();\n const url = new URL(path.replace(/:([a-z]\\w*)/gi, (_, w) => encodeURIComponent(params[w])), base);\n if (query) {\n if (!(query instanceof URLSearchParams)) {\n query = createURLSearchParams(query);\n }\n query.forEach((value, name) => url.searchParams.append(name, value));\n }\n if (this.headers && headers) {\n const h = new Headers(this.headers);\n new Headers(headers).forEach((value, name) => h.set(name, value));\n headers = h;\n }\n else {\n headers = new Headers(this.headers || headers);\n }\n if (body !== undefined &&\n body !== null &&\n ![\"GET\", \"HEAD\"].includes(method)) {\n const contentType = headers.get(\"content-type\") || \"\";\n if ((!contentType &&\n body &&\n Object.prototype.toString.call(body) === \"[object Object]\") ||\n contentType.startsWith(\"application/json\")) {\n if (!headers.has(\"content-type\")) {\n headers.set(\"content-type\", \"application/json\");\n }\n body = JSON.stringify(body);\n }\n else if (contentType.startsWith(\"multipart/form-data\") &&\n body &&\n !(body instanceof FormData)) {\n body = createFormData(body);\n }\n else if (contentType.startsWith(\"application/x-www-form-urlencoded\") &&\n body &&\n !(body instanceof URLSearchParams)) {\n body = createURLSearchParams(body);\n }\n }\n const ctx = {\n url,\n options: {\n method,\n headers,\n body: body,\n },\n ...rest,\n };\n return compose(use)(ctx, () => fetch(ctx.url.href, ctx.options).then((response) => {\n ctx.response = response;\n let body = Promise.resolve(response);\n if (![\"HEAD\", \"head\"].includes(ctx.options.method)) {\n const responseType = response.headers.get(\"content-type\");\n if (responseType) {\n if (responseType.startsWith(\"application/json\")) {\n body = response.json();\n }\n else if (responseType.startsWith(\"text/\")) {\n body = response.text();\n }\n }\n }\n if (response.ok) {\n return body;\n }\n else {\n return body.then((e) => {\n throw e;\n });\n }\n }));\n }\n get(path, query, options) {\n return this.fetch(path, {\n ...options,\n method: \"GET\",\n query,\n });\n }\n post(path, body, options) {\n return this.fetch(path, {\n ...options,\n method: \"POST\",\n body,\n });\n }\n put(path, body, options) {\n return this.fetch(path, {\n ...options,\n method: \"PUT\",\n body,\n });\n }\n patch(path, body, options) {\n return this.fetch(path, {\n ...options,\n method: \"PATCH\",\n body,\n });\n }\n delete(path, query, options) {\n return this.fetch(path, {\n ...options,\n method: \"DELETE\",\n query,\n });\n }\n head(path, query, options) {\n return this.fetch(path, {\n ...options,\n method: \"HEAD\",\n query,\n });\n }\n purge(path, query, options) {\n return this.fetch(path, {\n ...options,\n method: \"PURGE\",\n query,\n });\n }\n}\nexport default Teleman;\nexport { Teleman };\nexport const teleman = new Teleman();\n//# sourceMappingURL=index.js.map"],"names":["compose"],"mappings":"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","x_google_ignoreList":[0]}
{"version":3,"file":"index.js","sources":["../node_modules/koa-compose/index.js","../src/index.ts"],"sourcesContent":["'use strict'\n\n/**\n * Expose compositor.\n */\n\nmodule.exports = compose\n\n/**\n * Compose `middleware` returning\n * a fully valid middleware comprised\n * of all those which are passed.\n *\n * @param {Array} middleware\n * @return {Function}\n * @api public\n */\n\nfunction compose (middleware) {\n if (!Array.isArray(middleware)) throw new TypeError('Middleware stack must be an array!')\n for (const fn of middleware) {\n if (typeof fn !== 'function') throw new TypeError('Middleware must be composed of functions!')\n }\n\n /**\n * @param {Object} context\n * @return {Promise}\n * @api public\n */\n\n return function (context, next) {\n // last called middleware #\n let index = -1\n return dispatch(0)\n function dispatch (i) {\n if (i <= index) return Promise.reject(new Error('next() called multiple times'))\n index = i\n let fn = middleware[i]\n if (i === middleware.length) fn = next\n if (!fn) return Promise.resolve()\n try {\n return Promise.resolve(fn(context, dispatch.bind(null, i + 1)));\n } catch (err) {\n return Promise.reject(err)\n }\n }\n }\n}\n","import compose from 'koa-compose'\n\nexport type PrimitiveType = string | number | boolean | null | undefined\n\nexport type SerializableData =\n | string\n | number\n | boolean\n | null\n | undefined\n | SerializableData[]\n | { [name: string]: SerializableData }\n\nexport type ReqOptions = {\n method?: Method | MethodLowercase\n base?: string\n headers?: Headers | Record<string, string>\n query?:\n | URLSearchParams\n | string\n | Record<string, PrimitiveType>\n | [string, PrimitiveType][]\n params?: Record<string, string | number | boolean>\n body?: ReqBody | SerializableData\n use?: Middleware[]\n [index: string]: unknown\n}\n\nexport type Method =\n | 'GET'\n | 'POST'\n | 'PUT'\n | 'DELETE'\n | 'PATCH'\n | 'HEAD'\n | 'PURGE'\nexport type MethodLowercase =\n | 'get'\n | 'post'\n | 'put'\n | 'delete'\n | 'patch'\n | 'head'\n | 'purge'\nexport type ReqBody =\n | string\n | FormData\n | URLSearchParams\n | Blob\n | BufferSource\n | ReadableStream\n\nexport type MiddlewareCtx = {\n url: URL\n\n options: {\n method: Method\n headers: Headers\n body: ReqBody\n }\n\n response?: Response\n [name: string]: unknown\n}\n\nexport type Middleware = (\n ctx: MiddlewareCtx,\n next: () => Promise<any> // eslint-disable-line @typescript-eslint/no-explicit-any\n) => unknown\nexport type Query =\n | string\n | Record<string, PrimitiveType>\n | [string, PrimitiveType][]\nexport type FormBody =\n | Record<string, PrimitiveType | Blob>\n | [string, PrimitiveType | Blob, string?][]\n\nexport function createURLSearchParams(query: Query) {\n if (query.constructor === String) {\n return new URLSearchParams(query)\n }\n\n if (Object.prototype.toString.call(query) === '[object Object]') {\n query = Object.entries(query)\n }\n\n const q = new URLSearchParams()\n\n for (const [name, value] of query as [string, PrimitiveType][]) {\n if (value !== null && value !== undefined) {\n q.append(name, value as string)\n }\n }\n\n return q\n}\n\nexport function createFormData(data: FormBody) {\n if (Object.prototype.toString.call(data) === '[object Object]') {\n data = Object.entries(data)\n }\n\n const f = new FormData()\n\n for (const [name, value, filename] of data as [\n string,\n PrimitiveType | Blob,\n string?\n ][]) {\n if (value !== null && value !== undefined) {\n if (filename) {\n f.append(name, value as Blob, filename)\n } else {\n f.append(name, value as string)\n }\n }\n }\n\n return f\n}\n\nclass Teleman {\n base?: string\n headers: Headers\n middleware: Middleware[] = []\n\n constructor({\n base,\n headers\n }: {\n base?: string\n headers?: Headers | Record<string, string>\n } = {}) {\n if (base) {\n this.base = base\n } else {\n try {\n // defaults to document.baseURI in browser\n this.base = document.baseURI\n } catch (e) {\n // in node.js, ignore\n }\n }\n\n this.headers = new Headers(headers)\n }\n\n use(middleware: Middleware) {\n this.middleware.push(middleware)\n return this\n }\n\n async fetch<T>(\n path: string,\n {\n method = 'GET',\n base = this.base,\n headers,\n query,\n params = {},\n body,\n use = this.middleware,\n ...rest\n }: ReqOptions = {}\n ): Promise<T> {\n method = method.toUpperCase() as Method\n const url = new URL(\n path.replace(/:([a-z]\\w*)/gi, (_, w) => encodeURIComponent(params[w])),\n base\n )\n\n if (query) {\n if (!(query instanceof URLSearchParams)) {\n query = createURLSearchParams(query)\n }\n\n query.forEach((value, name) => url.searchParams.append(name, value))\n }\n\n if (this.headers && headers) {\n const h = new Headers(this.headers)\n new Headers(headers).forEach((value, name) => h.set(name, value))\n headers = h\n } else {\n headers = new Headers(this.headers || headers)\n }\n\n if (\n body !== undefined &&\n body !== null &&\n !['GET', 'HEAD'].includes(method)\n ) {\n const contentType = headers.get('content-type') || ''\n\n if (\n (!contentType &&\n body &&\n Object.prototype.toString.call(body) === '[object Object]') ||\n contentType.startsWith('application/json')\n ) {\n if (!headers.has('content-type')) {\n headers.set('content-type', 'application/json')\n }\n\n body = JSON.stringify(body)\n } else if (\n contentType.startsWith('multipart/form-data') &&\n body &&\n !(body instanceof FormData)\n ) {\n body = createFormData(body as FormBody)\n } else if (\n contentType.startsWith('application/x-www-form-urlencoded') &&\n body &&\n !(body instanceof URLSearchParams)\n ) {\n body = createURLSearchParams(body as Query)\n }\n }\n\n const ctx: MiddlewareCtx = {\n url,\n\n options: {\n method,\n headers,\n body: body as ReqBody\n },\n\n ...rest\n }\n\n return <Promise<T>>compose(use)(ctx, () =>\n fetch(ctx.url.href, ctx.options).then(response => {\n ctx.response = response\n let body: Promise<unknown> = Promise.resolve(response)\n\n if (!['HEAD', 'head'].includes(ctx.options.method)) {\n const responseType = response.headers.get('content-type')\n\n if (responseType) {\n if (responseType.startsWith('application/json')) {\n body = response.json()\n } else if (responseType.startsWith('text/')) {\n body = response.text()\n }\n }\n }\n\n if (response.ok) {\n return body\n } else {\n return body.then(e => {\n throw e\n })\n }\n })\n )\n }\n\n get<T>(path: string, query?: Query, options?: ReqOptions) {\n return this.fetch<T>(path, {\n ...options,\n method: 'GET',\n query\n })\n }\n\n post<T>(\n path: string,\n body?: ReqBody | SerializableData,\n options?: ReqOptions\n ) {\n return this.fetch<T>(path, {\n ...options,\n method: 'POST',\n body\n })\n }\n\n put<T>(\n path: string,\n body?: ReqBody | SerializableData,\n options?: ReqOptions\n ) {\n return this.fetch<T>(path, {\n ...options,\n method: 'PUT',\n body\n })\n }\n\n patch<T>(\n path: string,\n body?: ReqBody | SerializableData,\n options?: ReqOptions\n ) {\n return this.fetch<T>(path, {\n ...options,\n method: 'PATCH',\n body\n })\n }\n\n delete<T>(path: string, query?: Query, options?: ReqOptions) {\n return this.fetch<T>(path, {\n ...options,\n method: 'DELETE',\n query\n })\n }\n\n head<T>(path: string, query?: Query, options?: ReqOptions) {\n return this.fetch<T>(path, {\n ...options,\n method: 'HEAD',\n query\n })\n }\n\n purge<T>(path: string, query?: Query, options?: ReqOptions) {\n return this.fetch<T>(path, {\n ...options,\n method: 'PURGE',\n query\n })\n }\n}\n\nexport default Teleman\nexport { Teleman }\nexport const teleman = new Teleman()\n"],"names":[],"mappings":"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","x_google_ignoreList":[0]}
{
"name": "teleman",
"version": "0.7.4",
"version": "0.8.0",
"description": "A browser and node.js fetch API wrapper.",

@@ -14,3 +14,2 @@ "main": "./dist/index.cjs",

"scripts": {
"test": "start-server-and-test 'ts-node-esm test/test-server.ts' 3000 jest",
"build": "rollup -c rollup.config.esm.js && rollup -c rollup.config.cjs.js && tsc -d --emitDeclarationOnly --declarationDir dist"

@@ -40,25 +39,13 @@ },

"devDependencies": {
"@jest/globals": "^29.6.4",
"@rollup/plugin-commonjs": "^25.0.4",
"@rollup/plugin-node-resolve": "^15.2.1",
"@rollup/plugin-typescript": "^11.1.3",
"@types/koa": "^2.13.8",
"@types/koa-compose": "^3.2.5",
"@types/node": "^20.5.7",
"@typescript-eslint/eslint-plugin": "^6.5.0",
"@typescript-eslint/parser": "^6.5.0",
"eslint": "^8.48.0",
"eslint-config-prettier": "^9.0.0",
"jest": "^29.6.4",
"koa": "^2.14.2",
"koa-pilot": "^0.7.2",
"prettier": "^3.0.2",
"prettier-plugin-organize-imports": "^3.2.3",
"rollup": "^3.28.1",
"start-server-and-test": "^2.0.0",
"ts-jest": "^29.1.1",
"ts-node": "^10.9.1",
"tslib": "^2.6.2",
"typescript": "^5.2.2"
"@rollup/plugin-commonjs": "^28.0.6",
"@rollup/plugin-node-resolve": "^16.0.1",
"@rollup/plugin-typescript": "^12.1.3",
"@types/bun": "^1.2.17",
"@types/koa-compose": "^3.2.8",
"@types/node": "^24.0.3",
"prettier": "^3.6.0",
"rollup": "^4.44.0",
"tslib": "^2.8.1",
"typescript": "^5.8.3"
}
}
+103
-148
# Teleman
A tiny (~2kb after gzipped) `fetch` API wrapper.
**Teleman** is a minimalist wrapper around the native `fetch` API. It weighs ~2 kB (gzipped) yet adds everything you miss in vanilla `fetch`:
## Features
* Tiny, only about 2kb after gzipped.
* Support middleware.
* Return decoded response body.
* Handle `response.ok` for you.
* A Koa-style middleware pipeline.
* Automatic serialisation of query strings, path parameters and request bodies.
* Automatic response decoding (`json()`, `text()`, or raw `Response`).
* Built-in error handling – non-`2xx` responses reject the promise.
* First-class TypeScript support.
## Installation

@@ -17,189 +18,143 @@

NOTE: The code is written in ES2020 syntax and not transpiled.
To use it in old browsers, you should transpile the code using tools such as Babel.
## Usage
## Quick start
```js
import Teleman from 'teleman'
```ts
import Teleman from "teleman";
async function main() {
const api = new Teleman({
base: 'http://api.example.com'
});
const api = new Teleman({
base: "https://api.example.com", // optional base URL
});
const article = await api.get('/articles', { id: 123 });
// GET /articles/123?draft=false
const article = await api.get("/articles/:id", {
id: 123,
draft: false,
});
// post JSON
await api.post('/articles', { title: 'Hello', content: '# Hello' });
// POST /articles (Content-Type: application/json)
await api.post("/articles", {
title: "Hello",
content: "# Hello",
});
// post with Content-Type: multipart/form-data
await api.post('/upload', new FormData(document.forms[0]));
}
// POST /upload (Content-Type: multipart/form-data)
await api.post("/upload", new FormData(document.forms[0]));
```
### Singleton
You can also use Teleman directly without creating an instance.
```js
import { teleman } from 'teleman';
### Singleton helper
For tiny scripts you do not have to create an instance:
teleman.get(url, query, options);
teleman.post(url, body, options);
teleman.put(url, body, options);
teleman.patch(url, body, options);
teleman.delete(url, query, options);
teleman.head(url, query, options);
teleman.purge(url, query, options);
teleman.use(middleware);
```
```ts
import { teleman } from "teleman";
## Constructor
```js
new Teleman({ base, headers })
const data = await teleman.get("https://example.com/data.json");
```
Creates a Teleman instance.
### base
`String`. Optional. Base URL. In browser, it's default value is `document.baseURI`.
## Creating an instance
### headers
`Object`. Optional. Default headers. It can be a simple key-value object or
[Headers](https://developer.mozilla.org/en-US/docs/Web/API/Headers/Headers) object.
```ts
new Teleman(options?: {
base?: string; // Base URL – defaults to document.baseURI in browsers
headers?: HeadersInit; // Default headers for every request
});
```
## Methods
### instance.fetch()
## API reference
```js
instance.fetch(url, {
method = 'GET',
base = this.base,
headers,
query,
params = {},
body,
use = this.middleware,
...rest
} = {})
### `instance.fetch<T>(path, options?) : Promise<T>`
Complete control – all shortcut methods ultimately call `fetch()`.
```ts
interface FetchOptions {
method?: "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "PURGE";
base?: string; // Overrides instance.base for this call only
headers?: HeadersInit; // Extra headers (merged with instance headers)
query?: URLSearchParams | string | Record<string, Primitive> | Array<[string, Primitive]>;
params?: Record<string, string | number | boolean>; // URL path parameters
body?: BodyInit | SerializableData; // Serialised automatically when necessary
use?: Middleware[]; // Extra middleware for *this* request
// ...any additional fields you attach to the middleware context
}
```
#### Parameters
`fetch()` returns a promise that resolves to:
##### url
`String`. The URL of the request. If it's a relative URL, it's relative to `base` parameter.
* `response.json()` if the server replies with `Content-Type: application/json`.
* `response.text()` for any `text/*` response.
* The raw `Response` object otherwise.
##### base
`String`. Base URL. The request URL will be `new URL(url, base)`.
The promise rejects when `response.ok === false` and resolves to the decoded **body** otherwise – you do **not** have to check the status code yourself.
##### method
`String`. HTTP methods. `GET`, `POST`, `PUT`, `PATCH`, `DELETE`, `HEAD`, `PURGE`. Defaults to 'GET'.
#### Shortcut methods
##### headers
`Object` | [Headers](https://developer.mozilla.org/en-US/docs/Web/API/Headers). HTTP headers.
It will be merged with instance's default headers.
##### query
`String` | `Object` | `Array` | [URLSearchParams](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams).
The query string appends to the URL. It takes the same format as
[URLSearchParams](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams/URLSearchParams) constructor's param.
##### params
`Object`. URL path params.
```js
instance.fetch('/articles/:id', { params: { id: 1 } })
```ts
instance.get<T>(path, query?, options?)
instance.post<T>(path, body?, options?)
instance.put<T>(path, body?, options?)
instance.patch<T>(path, body?, options?)
instance.delete<T>(path, query?, options?)
instance.head<T>(path, query?, options?)
instance.purge<T>(path, query?, options?)
```
It will use `encodeURIComponent()` to encode the values.
All shortcut methods forward to `fetch()` with the corresponding HTTP verb.
##### body
`Object` | `FormData` | `Blob` | `BufferSource` | `URLSearchParams` | `String`. The request body.
If the body is a plain object, it will be converted to other type according to `content-type` of `headers`:
* not set: to JSON string, and set `content-type` to `application/json`.
* `application/json`: to JSON string.
* `multipart/form-data`: to FormData.
* `application/x-www-form-urlencoded`: to URLSearchParams.
## Middleware
##### use
`Array<Middleware>`. Middleware functions to use. Defaults to `instance.middleware` array.
Teleman borrows the elegant middleware pattern from Koa. A middleware is an async function receiving a context object and a `next()` callback:
##### ...rest
Other parameters will be set into the context object.
```ts
import type { MiddlewareCtx, Middleware } from "teleman";
#### Return Value
`instance.fetch()` returns a promise.
const logger: Middleware = async (ctx: MiddlewareCtx, next) => {
const start = Date.now();
const data = await next(); // wait for the request to finish
const ms = Date.now() - start;
console.info(`${ctx.options.method} ${ctx.url.href} – ${ms}ms`);
return data; // you may also transform the data
};
According to `content-type` header of the response, it will resolve/reject (depends on `response.ok`) to different types:
* `application/json`: `response.json()`
* `text/*`: `response.text()`
* Others: the `response` object as is.
api.use(logger);
```
If any error occurs, the promise will be rejected with that error.
`ctx` contains:
### Shortcut methods
```js
instance.get(url, query, options)
instance.post(url, body, options)
instance.put(url, body, options)
instance.patch(url, body, options)
instance.delete(url, query, options)
instance.head(url, query, options)
instance.purge(url, query, options)
```ts
interface MiddlewareCtx {
url: URL; // fully resolved URL (after params & query)
options: {
method: string;
headers: Headers;
body: BodyInit | null;
};
response?: Response; // attached after await next()
// plus any custom fields you passed through options
}
```
### instance.use(middleware)
Add the given middleware to `instance.middleware` array. It returns `this` so is chainable.
Within middleware you may mutate `ctx.url` / `ctx.options` to influence the outgoing request **or** inspect & transform the decoded response.
#### Parameters
##### middleware
`Function`. The middleware function to use.
```js
instance
.use(async(ctx, next) => {
try {
return await next();
} catch (e) {
alert(e?.message || 'fetch failed');
throw e;
}
});
.use(async(ctx, next) => {
const start = Date.now();
const data = await next();
const ms = Date.now() - start;
console.log(`${ctx.options.method} ${ctx.url.href} - ${ms}ms`);
// you can modify the data then return it
return {
...data,
foo: data.foo || 0
};
})
```
## Utility helpers
#### ctx
```js
{
url, // URL object
options: { method, headers, body },
response, // available after `await next()`
...rest // additional parameters passed from `instance.fetch()` options
}
```
The package exports two helpers that are also used internally. They can be handy when you need stand-alone conversions:
`url` and `options` will be used to call the `fetch()` function:
```ts
import { createURLSearchParams, createFormData } from "teleman";
```js
fetch(ctx.url.href, ctx.options)
const qs = createURLSearchParams({ foo: 1, bar: "baz" });
const form = createFormData({ file: myBlob, name: "avatar.png" });
```
You can modify the context properties to interfere the request and response.
#### next
A middleware function should receive the response body from `next()`, and can optionally modify the data.
Finally it should return the data.
## Browser & Node support
Teleman uses modern Web APIs (`fetch`, `Headers`, `URL`). It runs in all evergreen browsers and Node ≥ 18. No transpilation is required, but you may transpile/ponyfill `fetch` to target legacy environments.
## License
[MIT](LICENSE)

@@ -1,13 +0,13 @@

import commonjs from "@rollup/plugin-commonjs";
import resolve from "@rollup/plugin-node-resolve";
import typescript from "@rollup/plugin-typescript";
import commonjs from '@rollup/plugin-commonjs'
import resolve from '@rollup/plugin-node-resolve'
import typescript from '@rollup/plugin-typescript'
export default {
input: "src/index.ts",
input: 'src/index.ts',
output: {
format: "cjs",
file: "dist/index.cjs",
format: 'cjs',
file: 'dist/index.cjs',
sourcemap: true,
exports: "named",
exports: 'named'
},

@@ -17,3 +17,3 @@

external: ["koa-compose"],
};
external: ['koa-compose']
}

@@ -1,15 +0,15 @@

import commonjs from "@rollup/plugin-commonjs";
import resolve from "@rollup/plugin-node-resolve";
import typescript from "@rollup/plugin-typescript";
import commonjs from '@rollup/plugin-commonjs'
import resolve from '@rollup/plugin-node-resolve'
import typescript from '@rollup/plugin-typescript'
export default {
input: "src/index.ts",
input: 'src/index.ts',
output: {
format: "esm",
file: "dist/index.js",
sourcemap: true,
format: 'esm',
file: 'dist/index.js',
sourcemap: true
},
plugins: [resolve(), commonjs(), typescript()],
};
plugins: [resolve(), commonjs(), typescript()]
}
+124
-124

@@ -1,4 +0,4 @@

import compose from "koa-compose";
import compose from 'koa-compose'
export type PrimitiveType = string | number | boolean | null | undefined;
export type PrimitiveType = string | number | boolean | null | undefined

@@ -12,8 +12,8 @@ export type SerializableData =

| SerializableData[]
| { [name: string]: SerializableData };
| { [name: string]: SerializableData }
export type ReqOptions = {
method?: Method | MethodLowercase;
base?: string;
headers?: Headers | Record<string, string>;
method?: Method | MethodLowercase
base?: string
headers?: Headers | Record<string, string>
query?:

@@ -23,25 +23,25 @@ | URLSearchParams

| Record<string, PrimitiveType>
| [string, PrimitiveType][];
params?: Record<string, string | number | boolean>;
body?: ReqBody | SerializableData;
use?: Middleware[];
[index: string]: unknown;
};
| [string, PrimitiveType][]
params?: Record<string, string | number | boolean>
body?: ReqBody | SerializableData
use?: Middleware[]
[index: string]: unknown
}
export type Method =
| "GET"
| "POST"
| "PUT"
| "DELETE"
| "PATCH"
| "HEAD"
| "PURGE";
| 'GET'
| 'POST'
| 'PUT'
| 'DELETE'
| 'PATCH'
| 'HEAD'
| 'PURGE'
export type MethodLowercase =
| "get"
| "post"
| "put"
| "delete"
| "patch"
| "head"
| "purge";
| 'get'
| 'post'
| 'put'
| 'delete'
| 'patch'
| 'head'
| 'purge'
export type ReqBody =

@@ -53,16 +53,16 @@ | string

| BufferSource
| ReadableStream;
| ReadableStream
export type MiddlewareCtx = {
url: URL;
url: URL
options: {
method: Method;
headers: Headers;
body: ReqBody;
};
method: Method
headers: Headers
body: ReqBody
}
response?: Response;
[name: string]: unknown;
};
response?: Response
[name: string]: unknown
}

@@ -72,37 +72,37 @@ export type Middleware = (

next: () => Promise<any> // eslint-disable-line @typescript-eslint/no-explicit-any
) => unknown;
) => unknown
export type Query =
| string
| Record<string, PrimitiveType>
| [string, PrimitiveType][];
| [string, PrimitiveType][]
export type FormBody =
| Record<string, PrimitiveType | Blob>
| [string, PrimitiveType | Blob, string?][];
| [string, PrimitiveType | Blob, string?][]
function createURLSearchParams(query: Query) {
export function createURLSearchParams(query: Query) {
if (query.constructor === String) {
return new URLSearchParams(query);
return new URLSearchParams(query)
}
if (Object.prototype.toString.call(query) === "[object Object]") {
query = Object.entries(query);
if (Object.prototype.toString.call(query) === '[object Object]') {
query = Object.entries(query)
}
const q = new URLSearchParams();
const q = new URLSearchParams()
for (const [name, value] of query as [string, PrimitiveType][]) {
if (value !== null && value !== undefined) {
q.append(name, value as string);
q.append(name, value as string)
}
}
return q;
return q
}
function createFormData(data: FormBody) {
if (Object.prototype.toString.call(data) === "[object Object]") {
data = Object.entries(data);
export function createFormData(data: FormBody) {
if (Object.prototype.toString.call(data) === '[object Object]') {
data = Object.entries(data)
}
const f = new FormData();
const f = new FormData()

@@ -116,5 +116,5 @@ for (const [name, value, filename] of data as [

if (filename) {
f.append(name, value as Blob, filename);
f.append(name, value as Blob, filename)
} else {
f.append(name, value as string);
f.append(name, value as string)
}

@@ -124,23 +124,23 @@ }

return f;
return f
}
class Teleman {
base?: string;
headers: Headers;
middleware: Middleware[] = [];
base?: string
headers: Headers
middleware: Middleware[] = []
constructor({
base,
headers,
headers
}: {
base?: string;
headers?: Headers | Record<string, string>;
base?: string
headers?: Headers | Record<string, string>
} = {}) {
if (base) {
this.base = base;
this.base = base
} else {
try {
// defaults to document.baseURI in browser
this.base = document.baseURI;
this.base = document.baseURI
} catch (e) {

@@ -151,8 +151,8 @@ // in node.js, ignore

this.headers = new Headers(headers);
this.headers = new Headers(headers)
}
use(middleware: Middleware) {
this.middleware.push(middleware);
return this;
this.middleware.push(middleware)
return this
}

@@ -163,3 +163,3 @@

{
method = "GET",
method = 'GET',
base = this.base,

@@ -174,22 +174,22 @@ headers,

): Promise<T> {
method = method.toUpperCase() as Method;
method = method.toUpperCase() as Method
const url = new URL(
path.replace(/:([a-z]\w*)/gi, (_, w) => encodeURIComponent(params[w])),
base
);
)
if (query) {
if (!(query instanceof URLSearchParams)) {
query = createURLSearchParams(query);
query = createURLSearchParams(query)
}
query.forEach((value, name) => url.searchParams.append(name, value));
query.forEach((value, name) => url.searchParams.append(name, value))
}
if (this.headers && headers) {
const h = new Headers(this.headers);
new Headers(headers).forEach((value, name) => h.set(name, value));
headers = h;
const h = new Headers(this.headers)
new Headers(headers).forEach((value, name) => h.set(name, value))
headers = h
} else {
headers = new Headers(this.headers || headers);
headers = new Headers(this.headers || headers)
}

@@ -200,5 +200,5 @@

body !== null &&
!["GET", "HEAD"].includes(method)
!['GET', 'HEAD'].includes(method)
) {
const contentType = headers.get("content-type") || "";
const contentType = headers.get('content-type') || ''

@@ -208,22 +208,22 @@ if (

body &&
Object.prototype.toString.call(body) === "[object Object]") ||
contentType.startsWith("application/json")
Object.prototype.toString.call(body) === '[object Object]') ||
contentType.startsWith('application/json')
) {
if (!headers.has("content-type")) {
headers.set("content-type", "application/json");
if (!headers.has('content-type')) {
headers.set('content-type', 'application/json')
}
body = JSON.stringify(body);
body = JSON.stringify(body)
} else if (
contentType.startsWith("multipart/form-data") &&
contentType.startsWith('multipart/form-data') &&
body &&
!(body instanceof FormData)
) {
body = createFormData(body as FormBody);
body = createFormData(body as FormBody)
} else if (
contentType.startsWith("application/x-www-form-urlencoded") &&
contentType.startsWith('application/x-www-form-urlencoded') &&
body &&
!(body instanceof URLSearchParams)
) {
body = createURLSearchParams(body as Query);
body = createURLSearchParams(body as Query)
}

@@ -238,21 +238,21 @@ }

headers,
body: body as ReqBody,
body: body as ReqBody
},
...rest,
};
...rest
}
return <Promise<T>>compose(use)(ctx, () =>
fetch(ctx.url.href, ctx.options).then((response) => {
ctx.response = response;
let body: Promise<unknown> = Promise.resolve(response);
fetch(ctx.url.href, ctx.options).then(response => {
ctx.response = response
let body: Promise<unknown> = Promise.resolve(response)
if (!["HEAD", "head"].includes(ctx.options.method)) {
const responseType = response.headers.get("content-type");
if (!['HEAD', 'head'].includes(ctx.options.method)) {
const responseType = response.headers.get('content-type')
if (responseType) {
if (responseType.startsWith("application/json")) {
body = response.json();
} else if (responseType.startsWith("text/")) {
body = response.text();
if (responseType.startsWith('application/json')) {
body = response.json()
} else if (responseType.startsWith('text/')) {
body = response.text()
}

@@ -263,10 +263,10 @@ }

if (response.ok) {
return body;
return body
} else {
return body.then((e) => {
throw e;
});
return body.then(e => {
throw e
})
}
})
);
)
}

@@ -277,5 +277,5 @@

...options,
method: "GET",
query,
});
method: 'GET',
query
})
}

@@ -290,5 +290,5 @@

...options,
method: "POST",
body,
});
method: 'POST',
body
})
}

@@ -303,5 +303,5 @@

...options,
method: "PUT",
body,
});
method: 'PUT',
body
})
}

@@ -316,5 +316,5 @@

...options,
method: "PATCH",
body,
});
method: 'PATCH',
body
})
}

@@ -325,5 +325,5 @@

...options,
method: "DELETE",
query,
});
method: 'DELETE',
query
})
}

@@ -334,5 +334,5 @@

...options,
method: "HEAD",
query,
});
method: 'HEAD',
query
})
}

@@ -343,10 +343,10 @@

...options,
method: "PURGE",
query,
});
method: 'PURGE',
query
})
}
}
export default Teleman;
export { Teleman };
export const teleman = new Teleman();
export default Teleman
export { Teleman }
export const teleman = new Teleman()

@@ -1,133 +0,170 @@

import { expect, test } from "@jest/globals";
import { Teleman } from "../src";
import { expect, test, afterAll } from 'bun:test'
import { Teleman } from '../src'
const server = Bun.serve({
port: 0,
routes: {
'/': {
HEAD() {
return new Response(null, { status: 200 })
},
GET() {
return new Response('Hello World!')
}
},
'/headers': {
GET(req) {
const body = {
url: req.url,
method: req.method,
headers: Object.fromEntries(req.headers)
}
return Response.json(body)
}
}
},
fetch() {
return new Response('Not Found', { status: 404 })
},
error(error) {
console.error(error)
return new Response('Internal Server Error', { status: 500 })
}
})
console.log(server.url.href)
afterAll(() => {
server.stop()
})
const api = new Teleman({
base: "http://localhost:3000",
});
base: server.url.href
})
const api2 = new Teleman({
base: "http://localhost:3000",
base: server.url.href,
headers: {
foo: "1",
bar: "2",
},
});
foo: '1',
bar: '2'
}
})
api2.use(async (ctx, next) => {
try {
return await next();
return await next()
} catch (e) {
if (e instanceof Error) {
throw e;
throw e
} else {
throw {
code: ctx.response?.status,
message: e,
};
message: e
}
}
}
});
})
test("should fetch with correct url", () =>
api.fetch("/", {
use: [(ctx) => expect(ctx.url.href).toBe("http://localhost:3000/")],
}));
test('should fetch with correct url', () =>
api.fetch('/', {
use: [ctx => expect(ctx.url.href).toBe(server.url.href)]
}))
test("should read the response body if the response content-type is application/json", async () => {
const res = <Record<string, unknown>>await api.fetch("/headers");
expect(res.url).toBe("/headers");
});
test('should read the response body if the response content-type is application/json', async () => {
const res = <Record<string, unknown>>await api.fetch('/headers')
expect(res.url).toBe(`${server.url.href}headers`)
})
test("query can be object", () =>
api.fetch("/", {
test('query can be object', () =>
api.fetch('/', {
query: { a: 1, b: 2 },
use: [(ctx) => expect(ctx.url.href).toBe("http://localhost:3000/?a=1&b=2")],
}));
use: [ctx => expect(ctx.url.href).toBe(`${server.url.href}?a=1&b=2`)]
}))
test("query can be string", () =>
api.fetch("/", {
query: "a=1&b=2",
use: [(ctx) => expect(ctx.url.href).toBe("http://localhost:3000/?a=1&b=2")],
}));
test('query can be string', () =>
api.fetch('/', {
query: 'a=1&b=2',
use: [ctx => expect(ctx.url.href).toBe(`${server.url.href}?a=1&b=2`)]
}))
test("should convert body type of object to JSON by default", () =>
test('should convert body type of object to JSON by default', () =>
api.post(
"/",
'/',
{ a: 1, b: 2 },
{
use: [
(ctx) => {
expect(ctx.options.headers.get("content-type")).toBe(
"application/json"
);
expect(ctx.options.body).toBe('{"a":1,"b":2}');
},
],
ctx => {
expect(ctx.options.headers.get('content-type')).toBe(
'application/json'
)
expect(ctx.options.body).toBe('{"a":1,"b":2}')
}
]
}
));
))
test("should convert body type of object to FormData if the request content-type is set to multipart/form-data", () =>
test('should convert body type of object to FormData if the request content-type is set to multipart/form-data', () =>
api.post(
"/",
'/',
{ a: 1, b: 2 },
{
headers: { "content-type": "multipart/form-data" },
use: [(ctx) => expect(ctx.options.body).toBeInstanceOf(FormData)],
headers: { 'content-type': 'multipart/form-data' },
use: [ctx => expect(ctx.options.body).toBeInstanceOf(FormData)]
}
));
))
test("should convert body type of object to URLSearchParams if the request content-type is set to application/x-www-form-urlencoded", () =>
test('should convert body type of object to URLSearchParams if the request content-type is set to application/x-www-form-urlencoded', () =>
api.post(
"/",
'/',
{ a: 1, b: 2 },
{
headers: { "content-type": "application/x-www-form-urlencoded" },
use: [(ctx) => expect(ctx.options.body).toBeInstanceOf(URLSearchParams)],
headers: { 'content-type': 'application/x-www-form-urlencoded' },
use: [ctx => expect(ctx.options.body).toBeInstanceOf(URLSearchParams)]
}
));
))
test("should merge default headers with headers param", () =>
api2.fetch("/", {
headers: { foo: "11", baz: "3" },
test('should merge default headers with headers param', () =>
api2.fetch('/', {
headers: { foo: '11', baz: '3' },
use: [
(ctx) => {
expect(ctx.options.headers.get("foo")).toBe("11");
expect(ctx.options.headers.get("bar")).toBe("2");
expect(ctx.options.headers.get("baz")).toBe("3");
},
],
}));
ctx => {
expect(ctx.options.headers.get('foo')).toBe('11')
expect(ctx.options.headers.get('bar')).toBe('2')
expect(ctx.options.headers.get('baz')).toBe('3')
}
]
}))
test("should throw response body if response.ok is false", async () =>
await expect(api.get("/404")).rejects.toBe("Not Found"));
test('should throw response body if response.ok is false', async () =>
await expect(api.get('/404')).rejects.toBe('Not Found'))
test("should throw error if fetch failed", async () =>
await expect(api.get("http://127.0.0.1:65535/")).rejects.toThrow());
test('should throw error if fetch failed', async () =>
await expect(api.get('http://127.0.0.1:65535/')).rejects.toThrow())
test("should run middleware", async () =>
await expect(api2.get("/404")).rejects.toStrictEqual({
test('should run middleware', async () =>
await expect(api2.get('/404')).rejects.toStrictEqual({
code: 404,
message: "Not Found",
}));
message: 'Not Found'
}))
test("should request with PUT method", () =>
api.put("/", null, {
use: [(ctx) => expect(ctx.options.method).toBe("PUT")],
}));
test('should request with PUT method', () =>
api.put('/', null, {
use: [ctx => expect(ctx.options.method).toBe('PUT')]
}))
test("should request with PATCH method", () =>
api.patch("/", null, {
use: [(ctx) => expect(ctx.options.method).toBe("PATCH")],
}));
test('should request with PATCH method', () =>
api.patch('/', null, {
use: [ctx => expect(ctx.options.method).toBe('PATCH')]
}))
test("should request with DELETE method", () =>
api.delete("/", undefined, {
use: [(ctx) => expect(ctx.options.method).toBe("DELETE")],
}));
test('should request with DELETE method', () =>
api.delete('/', undefined, {
use: [ctx => expect(ctx.options.method).toBe('DELETE')]
}))
test("should request with HEAD method", () =>
api.head("/", undefined, {
use: [(ctx) => expect(ctx.options.method).toBe("HEAD")],
}));
test('should request with HEAD method', () =>
api.head('/', undefined, {
use: [ctx => expect(ctx.options.method).toBe('HEAD')]
}))

Sorry, the diff of this file is not supported yet

{
"root": true,
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint"],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"prettier"
],
"env": {
"browser": true,
"node": true
}
}
{
"plugins": [
"prettier-plugin-organize-imports"
]
}
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"editor.tabSize": 2
}
{
"preset": "ts-jest",
"collectCoverage": true
}
import Koa from "koa";
import Router from "koa-pilot";
const app = new Koa();
const router = new Router();
router.head("/", (ctx) => {
ctx.status = 200;
});
router.get("/", (ctx) => {
ctx.body = "Hello World!";
});
router.get("/headers", (ctx) => {
ctx.body = {
url: ctx.url,
method: ctx.method,
headers: ctx.headers,
};
});
app.use(router.middleware);
app.listen(3000, () => {
console.log("The server is listening on port 3000"); // eslint-disable-line no-console
});