@faasjs/request 0.0.2-beta.255 → 0.0.2-beta.314

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.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  网络请求库
4
4
 
5
- [![License: MIT](https://img.shields.io/npm/l/@faasjs/request.svg)](https://github.com/faasjs/faasjs/blob/master/packages/faasjs/request/LICENSE)
5
+ [![License: MIT](https://img.shields.io/npm/l/@faasjs/request.svg)](https://github.com/faasjs/faasjs/blob/main/packages/faasjs/request/LICENSE)
6
6
  [![NPM Stable Version](https://img.shields.io/npm/v/@faasjs/request/stable.svg)](https://www.npmjs.com/package/@faasjs/request)
7
7
  [![NPM Beta Version](https://img.shields.io/npm/v/@faasjs/request/beta.svg)](https://www.npmjs.com/package/@faasjs/request)
8
8
 
@@ -1,76 +1,77 @@
1
- /// <reference types="node" />
2
- import * as http from 'http';
3
- export declare type Request = {
4
- headers?: http.OutgoingHttpHeaders;
5
- method?: string;
6
- host?: string;
7
- path?: string;
8
- query?: http.OutgoingHttpHeaders;
9
- body?: {
10
- [key: string]: any;
11
- };
12
- };
13
- export declare type Response<T = any> = {
14
- request?: Request;
15
- statusCode?: number;
16
- statusMessage?: string;
17
- headers: http.OutgoingHttpHeaders;
18
- body: T;
19
- };
20
- export declare type RequestOptions = {
21
- /** 请求头 */
22
- headers?: http.OutgoingHttpHeaders;
23
- /** 请求方法,默认为 GET */
24
- method?: string;
25
- /** 请求参数,放置于 path 后,若需放置在 body 中,请使用 body 参数 */
26
- query?: {
27
- [key: string]: any;
28
- };
29
- /** 请求体 */
30
- body?: {
31
- [key: string]: any;
32
- } | string;
33
- /** 最长耗时,单位为毫秒 */
34
- timeout?: number;
35
- /** HTTP 认证头,格式为 user:password */
36
- auth?: string;
37
- /** 上传文件的完整路径 */
38
- file?: string;
39
- /** 下载流,用于直接将响应内容保存到本地文件,通过 fs.createWriteStream 创建 */
40
- downloadStream?: NodeJS.WritableStream;
41
- pfx?: Buffer;
42
- passphrase?: string;
43
- agent?: boolean;
44
- /** body 解析器,默认为 JSON.parse */
45
- parse?: (body: string) => any;
46
- };
47
- declare type Mock = (url: string, options: RequestOptions) => Promise<Response>;
48
- /**
49
- * 设置模拟请求
50
- * @param handler {function | null} 模拟函数,若设置为 null 则表示清除模拟函数
51
- * @example setMock(async (url, options) => Promise.resolve({ headers: {}, statusCode: 200, body: { data: 'ok' } }))
52
- */
53
- export declare function setMock(handler: Mock | null): void;
54
- export declare function querystringify(obj: any): string;
55
- /**
56
- * 发起网络请求
57
- * @param {string} url 请求路径或完整网址
58
- * @param {object=} [options={}] 参数和配置
59
- * @param {string} [options.methd=GET] 请求方法
60
- * @param {object} [options.query={}] 请求参数,放置于 path 后,若需放置在 body 中,请使用 body 参数
61
- * @param {object} [options.headers={}] 请求头
62
- * @param {object=} options.body 请求体
63
- * @param {number=} options.timeout 最长耗时,单位为毫秒
64
- * @param {string=} options.auth HTTP 认证头,格式为 user:password
65
- * @param {string=} options.file 上传文件的完整路径
66
- * @param {WritableStream=} options.downloadStream 下载流,用于直接将响应内容保存到本地文件
67
- * @param {Buffer=} options.pfx pfx
68
- * @param {string=} options.passphrase passphrase
69
- * @param {boolean=} options.agent agent
70
- * @param {parse=} options.parse body 解析器,默认为 JSON.parse
71
- *
72
- * @returns {promise}
73
- * @url https://faasjs.com/doc/request.html
74
- */
75
- export declare function request<T = any>(url: string, { headers, method, query, body, timeout, auth, file, downloadStream, pfx, passphrase, agent, parse }?: RequestOptions): Promise<Response<T>>;
76
- export default request;
1
+ import * as http from 'http';
2
+
3
+ declare type Request = {
4
+ headers?: http.OutgoingHttpHeaders;
5
+ method?: string;
6
+ host?: string;
7
+ path?: string;
8
+ query?: http.OutgoingHttpHeaders;
9
+ body?: {
10
+ [key: string]: any;
11
+ };
12
+ };
13
+ declare type Response<T = any> = {
14
+ request?: Request;
15
+ statusCode?: number;
16
+ statusMessage?: string;
17
+ headers: http.OutgoingHttpHeaders;
18
+ body: T;
19
+ };
20
+ declare type RequestOptions = {
21
+ /** 请求头 */
22
+ headers?: http.OutgoingHttpHeaders;
23
+ /** 请求方法,默认为 GET */
24
+ method?: string;
25
+ /** 请求参数,放置于 path 后,若需放置在 body 中,请使用 body 参数 */
26
+ query?: {
27
+ [key: string]: any;
28
+ };
29
+ /** 请求体 */
30
+ body?: {
31
+ [key: string]: any;
32
+ } | string;
33
+ /** 最长耗时,单位为毫秒 */
34
+ timeout?: number;
35
+ /** HTTP 认证头,格式为 user:password */
36
+ auth?: string;
37
+ /** 上传文件的完整路径 */
38
+ file?: string;
39
+ /** 下载流,用于直接将响应内容保存到本地文件,通过 fs.createWriteStream 创建 */
40
+ downloadStream?: NodeJS.WritableStream;
41
+ pfx?: Buffer;
42
+ passphrase?: string;
43
+ agent?: boolean;
44
+ /** body 解析器,默认为 JSON.parse */
45
+ parse?: (body: string) => any;
46
+ };
47
+ declare type Mock = (url: string, options: RequestOptions) => Promise<Response>;
48
+ /**
49
+ * 设置模拟请求
50
+ * @param handler {function | null} 模拟函数,若设置为 null 则表示清除模拟函数
51
+ * @example setMock(async (url, options) => Promise.resolve({ headers: {}, statusCode: 200, body: { data: 'ok' } }))
52
+ */
53
+ declare function setMock(handler: Mock | null): void;
54
+ declare function querystringify(obj: any): string;
55
+ /**
56
+ * 发起网络请求
57
+ * @param {string} url 请求路径或完整网址
58
+ * @param {object=} [options={}] 参数和配置
59
+ * @param {string} [options.method=GET] 请求方法
60
+ * @param {object} [options.query={}] 请求参数,放置于 path 后,若需放置在 body 中,请使用 body 参数
61
+ * @param {object} [options.headers={}] 请求头
62
+ * @param {object=} options.body 请求体
63
+ * @param {number=} options.timeout 最长耗时,单位为毫秒
64
+ * @param {string=} options.auth HTTP 认证头,格式为 user:password
65
+ * @param {string=} options.file 上传文件的完整路径
66
+ * @param {WritableStream=} options.downloadStream 下载流,用于直接将响应内容保存到本地文件
67
+ * @param {Buffer=} options.pfx pfx
68
+ * @param {string=} options.passphrase passphrase
69
+ * @param {boolean=} options.agent agent
70
+ * @param {parse=} options.parse body 解析器,默认为 JSON.parse
71
+ *
72
+ * @returns {promise}
73
+ * @url https://faasjs.com/doc/request.html
74
+ */
75
+ declare function request<T = any>(url: string, { headers, method, query, body, timeout, auth, file, downloadStream, pfx, passphrase, agent, parse }?: RequestOptions): Promise<Response<T>>;
76
+
77
+ export { Request, RequestOptions, Response, request as default, querystringify, request, setMock };
package/dist/index.js ADDED
@@ -0,0 +1,214 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __defProps = Object.defineProperties;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
8
+ var __getProtoOf = Object.getPrototypeOf;
9
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
10
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
11
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
12
+ var __spreadValues = (a, b) => {
13
+ for (var prop in b || (b = {}))
14
+ if (__hasOwnProp.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ if (__getOwnPropSymbols)
17
+ for (var prop of __getOwnPropSymbols(b)) {
18
+ if (__propIsEnum.call(b, prop))
19
+ __defNormalProp(a, prop, b[prop]);
20
+ }
21
+ return a;
22
+ };
23
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
24
+ var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
25
+ var __export = (target, all) => {
26
+ for (var name in all)
27
+ __defProp(target, name, { get: all[name], enumerable: true });
28
+ };
29
+ var __reExport = (target, module2, copyDefault, desc) => {
30
+ if (module2 && typeof module2 === "object" || typeof module2 === "function") {
31
+ for (let key of __getOwnPropNames(module2))
32
+ if (!__hasOwnProp.call(target, key) && (copyDefault || key !== "default"))
33
+ __defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
34
+ }
35
+ return target;
36
+ };
37
+ var __toESM = (module2, isNodeMode) => {
38
+ return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", !isNodeMode && module2 && module2.__esModule ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
39
+ };
40
+ var __toCommonJS = /* @__PURE__ */ ((cache) => {
41
+ return (module2, temp) => {
42
+ return cache && cache.get(module2) || (temp = __reExport(__markAsModule({}), module2, 1), cache && cache.set(module2, temp), temp);
43
+ };
44
+ })(typeof WeakMap !== "undefined" ? /* @__PURE__ */ new WeakMap() : 0);
45
+
46
+ // src/index.ts
47
+ var src_exports = {};
48
+ __export(src_exports, {
49
+ default: () => src_default,
50
+ querystringify: () => querystringify,
51
+ request: () => request,
52
+ setMock: () => setMock
53
+ });
54
+ var http = __toESM(require("http"));
55
+ var https = __toESM(require("https"));
56
+ var import_url = require("url");
57
+ var import_fs = require("fs");
58
+ var import_path = require("path");
59
+ var import_logger = require("@faasjs/logger");
60
+ var mock = null;
61
+ function setMock(handler) {
62
+ mock = handler;
63
+ }
64
+ function querystringify(obj) {
65
+ const pairs = [];
66
+ let value;
67
+ let key;
68
+ for (key in obj) {
69
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
70
+ value = obj[key];
71
+ if (!value && (value === null || value === void 0 || isNaN(value))) {
72
+ value = "";
73
+ }
74
+ key = encodeURIComponent(key);
75
+ value = encodeURIComponent(value);
76
+ if (key === null || value === null)
77
+ continue;
78
+ pairs.push(key + "=" + value);
79
+ }
80
+ }
81
+ return pairs.length ? pairs.join("&") : "";
82
+ }
83
+ async function request(url, {
84
+ headers,
85
+ method,
86
+ query,
87
+ body,
88
+ timeout,
89
+ auth,
90
+ file,
91
+ downloadStream,
92
+ pfx,
93
+ passphrase,
94
+ agent,
95
+ parse
96
+ } = {
97
+ headers: {},
98
+ query: {}
99
+ }) {
100
+ const log = new import_logger.Logger("request");
101
+ if (mock)
102
+ return mock(url, {
103
+ headers,
104
+ method,
105
+ query,
106
+ body
107
+ });
108
+ if (query) {
109
+ if (!url.includes("?"))
110
+ url += "?";
111
+ else if (!url.endsWith("?"))
112
+ url += "&";
113
+ url += querystringify(query);
114
+ }
115
+ const uri = new import_url.URL(url);
116
+ const protocol = uri.protocol === "https:" ? https : http;
117
+ if (!uri.protocol)
118
+ throw Error("Unknown protocol");
119
+ const options = {
120
+ headers: {},
121
+ host: uri.host ? uri.host.replace(/:[0-9]+$/, "") : uri.host,
122
+ method: method ? method.toUpperCase() : "GET",
123
+ path: uri.pathname + uri.search,
124
+ query: {},
125
+ port: uri.port,
126
+ timeout,
127
+ auth,
128
+ pfx,
129
+ passphrase,
130
+ agent
131
+ };
132
+ for (const key in headers)
133
+ if (typeof headers[key] !== "undefined" && headers[key] !== null)
134
+ options.headers[key] = headers[key];
135
+ if (body && typeof body !== "string")
136
+ if (options.headers["Content-Type"] && options.headers["Content-Type"].toString().includes("application/x-www-form-urlencoded"))
137
+ body = querystringify(body);
138
+ else
139
+ body = JSON.stringify(body);
140
+ if (body && !options.headers["Content-Length"])
141
+ options.headers["Content-Length"] = Buffer.byteLength(body);
142
+ return await new Promise(function(resolve, reject) {
143
+ log.debug("request %j", __spreadProps(__spreadValues({}, options), {
144
+ body
145
+ }));
146
+ const req = protocol.request(options, function(res) {
147
+ if (downloadStream) {
148
+ res.pipe(downloadStream);
149
+ downloadStream.on("finish", function() {
150
+ resolve(void 0);
151
+ });
152
+ } else {
153
+ const raw = [];
154
+ res.on("data", (chunk) => {
155
+ raw.push(chunk);
156
+ });
157
+ res.on("end", () => {
158
+ const data = Buffer.concat(raw).toString();
159
+ log.timeEnd(url, "response %s %s %s", res.statusCode, res.headers["content-type"], data);
160
+ const response = Object.create(null);
161
+ response.request = options;
162
+ response.request.body = body;
163
+ response.statusCode = res.statusCode;
164
+ response.statusMessage = res.statusMessage;
165
+ response.headers = res.headers;
166
+ response.body = data;
167
+ if (response.body && response.headers["content-type"] && response.headers["content-type"].includes("application/json"))
168
+ try {
169
+ response.body = parse ? parse(response.body) : JSON.parse(response.body);
170
+ log.debug("response.parse JSON");
171
+ } catch (error) {
172
+ console.error(error);
173
+ }
174
+ if (response.statusCode >= 200 && response.statusCode < 400)
175
+ resolve(response);
176
+ else {
177
+ log.debug("response.error %j", response);
178
+ reject(response);
179
+ }
180
+ });
181
+ }
182
+ });
183
+ if (body)
184
+ req.write(body);
185
+ if (file) {
186
+ const crlf = "\r\n";
187
+ const boundary = `--${Math.random().toString(16)}`;
188
+ const delimiter = `${crlf}--${boundary}`;
189
+ const headers2 = [`Content-Disposition: form-data; name="file"; filename="${(0, import_path.basename)(file)}"${crlf}`];
190
+ const multipartBody = Buffer.concat([
191
+ Buffer.from(delimiter + crlf + headers2.join("") + crlf),
192
+ (0, import_fs.readFileSync)(file),
193
+ Buffer.from(`${delimiter}--`)
194
+ ]);
195
+ req.setHeader("Content-Type", "multipart/form-data; boundary=" + boundary);
196
+ req.setHeader("Content-Length", multipartBody.length);
197
+ req.write(multipartBody);
198
+ }
199
+ req.on("error", function(e) {
200
+ log.timeEnd(url, "response.error %j", e);
201
+ reject(e);
202
+ });
203
+ log.time(url);
204
+ req.end();
205
+ });
206
+ }
207
+ var src_default = request;
208
+ module.exports = __toCommonJS(src_exports);
209
+ // Annotate the CommonJS export names for ESM import in node:
210
+ 0 && (module.exports = {
211
+ querystringify,
212
+ request,
213
+ setMock
214
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,181 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __spreadValues = (a, b) => {
9
+ for (var prop in b || (b = {}))
10
+ if (__hasOwnProp.call(b, prop))
11
+ __defNormalProp(a, prop, b[prop]);
12
+ if (__getOwnPropSymbols)
13
+ for (var prop of __getOwnPropSymbols(b)) {
14
+ if (__propIsEnum.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ }
17
+ return a;
18
+ };
19
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
+
21
+ // src/index.ts
22
+ import * as http from "http";
23
+ import * as https from "https";
24
+ import { URL } from "url";
25
+ import { readFileSync } from "fs";
26
+ import { basename } from "path";
27
+ import { Logger } from "@faasjs/logger";
28
+ var mock = null;
29
+ function setMock(handler) {
30
+ mock = handler;
31
+ }
32
+ function querystringify(obj) {
33
+ const pairs = [];
34
+ let value;
35
+ let key;
36
+ for (key in obj) {
37
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
38
+ value = obj[key];
39
+ if (!value && (value === null || value === void 0 || isNaN(value))) {
40
+ value = "";
41
+ }
42
+ key = encodeURIComponent(key);
43
+ value = encodeURIComponent(value);
44
+ if (key === null || value === null)
45
+ continue;
46
+ pairs.push(key + "=" + value);
47
+ }
48
+ }
49
+ return pairs.length ? pairs.join("&") : "";
50
+ }
51
+ async function request(url, {
52
+ headers,
53
+ method,
54
+ query,
55
+ body,
56
+ timeout,
57
+ auth,
58
+ file,
59
+ downloadStream,
60
+ pfx,
61
+ passphrase,
62
+ agent,
63
+ parse
64
+ } = {
65
+ headers: {},
66
+ query: {}
67
+ }) {
68
+ const log = new Logger("request");
69
+ if (mock)
70
+ return mock(url, {
71
+ headers,
72
+ method,
73
+ query,
74
+ body
75
+ });
76
+ if (query) {
77
+ if (!url.includes("?"))
78
+ url += "?";
79
+ else if (!url.endsWith("?"))
80
+ url += "&";
81
+ url += querystringify(query);
82
+ }
83
+ const uri = new URL(url);
84
+ const protocol = uri.protocol === "https:" ? https : http;
85
+ if (!uri.protocol)
86
+ throw Error("Unknown protocol");
87
+ const options = {
88
+ headers: {},
89
+ host: uri.host ? uri.host.replace(/:[0-9]+$/, "") : uri.host,
90
+ method: method ? method.toUpperCase() : "GET",
91
+ path: uri.pathname + uri.search,
92
+ query: {},
93
+ port: uri.port,
94
+ timeout,
95
+ auth,
96
+ pfx,
97
+ passphrase,
98
+ agent
99
+ };
100
+ for (const key in headers)
101
+ if (typeof headers[key] !== "undefined" && headers[key] !== null)
102
+ options.headers[key] = headers[key];
103
+ if (body && typeof body !== "string")
104
+ if (options.headers["Content-Type"] && options.headers["Content-Type"].toString().includes("application/x-www-form-urlencoded"))
105
+ body = querystringify(body);
106
+ else
107
+ body = JSON.stringify(body);
108
+ if (body && !options.headers["Content-Length"])
109
+ options.headers["Content-Length"] = Buffer.byteLength(body);
110
+ return await new Promise(function(resolve, reject) {
111
+ log.debug("request %j", __spreadProps(__spreadValues({}, options), {
112
+ body
113
+ }));
114
+ const req = protocol.request(options, function(res) {
115
+ if (downloadStream) {
116
+ res.pipe(downloadStream);
117
+ downloadStream.on("finish", function() {
118
+ resolve(void 0);
119
+ });
120
+ } else {
121
+ const raw = [];
122
+ res.on("data", (chunk) => {
123
+ raw.push(chunk);
124
+ });
125
+ res.on("end", () => {
126
+ const data = Buffer.concat(raw).toString();
127
+ log.timeEnd(url, "response %s %s %s", res.statusCode, res.headers["content-type"], data);
128
+ const response = Object.create(null);
129
+ response.request = options;
130
+ response.request.body = body;
131
+ response.statusCode = res.statusCode;
132
+ response.statusMessage = res.statusMessage;
133
+ response.headers = res.headers;
134
+ response.body = data;
135
+ if (response.body && response.headers["content-type"] && response.headers["content-type"].includes("application/json"))
136
+ try {
137
+ response.body = parse ? parse(response.body) : JSON.parse(response.body);
138
+ log.debug("response.parse JSON");
139
+ } catch (error) {
140
+ console.error(error);
141
+ }
142
+ if (response.statusCode >= 200 && response.statusCode < 400)
143
+ resolve(response);
144
+ else {
145
+ log.debug("response.error %j", response);
146
+ reject(response);
147
+ }
148
+ });
149
+ }
150
+ });
151
+ if (body)
152
+ req.write(body);
153
+ if (file) {
154
+ const crlf = "\r\n";
155
+ const boundary = `--${Math.random().toString(16)}`;
156
+ const delimiter = `${crlf}--${boundary}`;
157
+ const headers2 = [`Content-Disposition: form-data; name="file"; filename="${basename(file)}"${crlf}`];
158
+ const multipartBody = Buffer.concat([
159
+ Buffer.from(delimiter + crlf + headers2.join("") + crlf),
160
+ readFileSync(file),
161
+ Buffer.from(`${delimiter}--`)
162
+ ]);
163
+ req.setHeader("Content-Type", "multipart/form-data; boundary=" + boundary);
164
+ req.setHeader("Content-Length", multipartBody.length);
165
+ req.write(multipartBody);
166
+ }
167
+ req.on("error", function(e) {
168
+ log.timeEnd(url, "response.error %j", e);
169
+ reject(e);
170
+ });
171
+ log.time(url);
172
+ req.end();
173
+ });
174
+ }
175
+ var src_default = request;
176
+ export {
177
+ src_default as default,
178
+ querystringify,
179
+ request,
180
+ setMock
181
+ };
package/package.json CHANGED
@@ -1,32 +1,35 @@
1
1
  {
2
2
  "name": "@faasjs/request",
3
- "version": "0.0.2-beta.255",
3
+ "version": "0.0.2-beta.314",
4
4
  "license": "MIT",
5
- "main": "lib/index.js",
6
- "module": "lib/index.es.js",
7
- "types": "lib/index.d.ts",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "module": "dist/index.mjs",
8
8
  "homepage": "https://faasjs.com/doc/request.html",
9
9
  "repository": {
10
10
  "type": "git",
11
11
  "url": "git+https://github.com/faasjs/faasjs.git",
12
12
  "directory": "packages/request"
13
13
  },
14
+ "bugs": {
15
+ "url": "https://github.com/faasjs/faasjs/issues"
16
+ },
17
+ "funding": "https://github.com/sponsors/faasjs",
14
18
  "scripts": {
15
- "prepack": "rm -rf ./lib && rollup -c && mv lib/*/src/* lib/"
19
+ "build": "rm -rf ./dist && tsup-node src/index.ts --format esm,cjs --dts"
16
20
  },
17
21
  "files": [
18
- "lib"
22
+ "dist"
19
23
  ],
20
24
  "peerDependencies": {
21
25
  "@faasjs/logger": "^0.0.2-beta.243"
22
26
  },
23
27
  "devDependencies": {
24
- "@types/debug": "*",
25
- "@types/jest": "*",
26
- "@types/node": "*",
27
- "rollup": "*",
28
- "rollup-plugin-typescript2": "*",
28
+ "tsup": "*",
29
29
  "typescript": "*"
30
30
  },
31
- "gitHead": "b44a8294ba8ed5b08cf56931f00e58fa9adfb6ce"
31
+ "engines": {
32
+ "npm": ">=8.0.0"
33
+ },
34
+ "gitHead": "60be0e54eb369177b416d109a3f9a5a12dedbf24"
32
35
  }
package/lib/index.es.js DELETED
@@ -1,176 +0,0 @@
1
- import * as http from 'http';
2
- import * as https from 'https';
3
- import { URL } from 'url';
4
- import { readFileSync } from 'fs';
5
- import { basename } from 'path';
6
- import { Logger } from '@faasjs/logger';
7
-
8
- let mock = null;
9
- /**
10
- * 设置模拟请求
11
- * @param handler {function | null} 模拟函数,若设置为 null 则表示清除模拟函数
12
- * @example setMock(async (url, options) => Promise.resolve({ headers: {}, statusCode: 200, body: { data: 'ok' } }))
13
- */
14
- function setMock(handler) {
15
- mock = handler;
16
- }
17
- function querystringify(obj) {
18
- const pairs = [];
19
- let value;
20
- let key;
21
- for (key in obj) {
22
- if (Object.prototype.hasOwnProperty.call(obj, key)) {
23
- value = obj[key];
24
- if (!value && (value === null || value === undefined || isNaN(value))) {
25
- value = '';
26
- }
27
- key = encodeURIComponent(key);
28
- value = encodeURIComponent(value);
29
- if (key === null || value === null)
30
- continue;
31
- pairs.push(key + '=' + value);
32
- }
33
- }
34
- return pairs.length ? pairs.join('&') : '';
35
- }
36
- /**
37
- * 发起网络请求
38
- * @param {string} url 请求路径或完整网址
39
- * @param {object=} [options={}] 参数和配置
40
- * @param {string} [options.methd=GET] 请求方法
41
- * @param {object} [options.query={}] 请求参数,放置于 path 后,若需放置在 body 中,请使用 body 参数
42
- * @param {object} [options.headers={}] 请求头
43
- * @param {object=} options.body 请求体
44
- * @param {number=} options.timeout 最长耗时,单位为毫秒
45
- * @param {string=} options.auth HTTP 认证头,格式为 user:password
46
- * @param {string=} options.file 上传文件的完整路径
47
- * @param {WritableStream=} options.downloadStream 下载流,用于直接将响应内容保存到本地文件
48
- * @param {Buffer=} options.pfx pfx
49
- * @param {string=} options.passphrase passphrase
50
- * @param {boolean=} options.agent agent
51
- * @param {parse=} options.parse body 解析器,默认为 JSON.parse
52
- *
53
- * @returns {promise}
54
- * @url https://faasjs.com/doc/request.html
55
- */
56
- async function request(url, { headers, method, query, body, timeout, auth, file, downloadStream, pfx, passphrase, agent, parse } = {
57
- headers: {},
58
- query: {}
59
- }) {
60
- const log = new Logger('request');
61
- if (mock)
62
- return mock(url, {
63
- headers,
64
- method,
65
- query,
66
- body
67
- });
68
- // 序列化 query
69
- if (query) {
70
- if (!url.includes('?'))
71
- url += '?';
72
- else if (!url.endsWith('?'))
73
- url += '&';
74
- url += querystringify(query);
75
- }
76
- // 处理 URL 并生成 options
77
- const uri = new URL(url);
78
- const protocol = uri.protocol === 'https:' ? https : http;
79
- if (!uri.protocol)
80
- throw Error('Unkonw protocol');
81
- const options = {
82
- headers: {},
83
- host: uri.host ? uri.host.replace(/:[0-9]+$/, '') : uri.host,
84
- method: method ? method.toUpperCase() : 'GET',
85
- path: uri.pathname + uri.search,
86
- query: {},
87
- port: uri.port,
88
- timeout,
89
- auth,
90
- pfx,
91
- passphrase,
92
- agent
93
- };
94
- // 处理 headers
95
- for (const key in headers)
96
- if (typeof headers[key] !== 'undefined' && headers[key] !== null)
97
- options.headers[key] = headers[key];
98
- // 序列化 body
99
- if (body && typeof body !== 'string')
100
- if (options.headers['Content-Type'] &&
101
- options.headers['Content-Type'].toString().includes('application/x-www-form-urlencoded'))
102
- body = querystringify(body);
103
- else
104
- body = JSON.stringify(body);
105
- if (body && !options.headers['Content-Length'])
106
- options.headers['Content-Length'] = Buffer.byteLength(body);
107
- return await new Promise(function (resolve, reject) {
108
- log.debug('request %O', {
109
- ...options,
110
- body
111
- });
112
- const req = protocol.request(options, function (res) {
113
- if (downloadStream) {
114
- res.pipe(downloadStream);
115
- downloadStream.on('finish', function () {
116
- resolve(undefined);
117
- });
118
- }
119
- else {
120
- const raw = [];
121
- res.on('data', (chunk) => {
122
- raw.push(chunk);
123
- });
124
- res.on('end', () => {
125
- const data = Buffer.concat(raw).toString();
126
- log.timeEnd(url, 'response %s %s %s', res.statusCode, res.headers['content-type'], data);
127
- const response = Object.create(null);
128
- response.request = options;
129
- response.request.body = body;
130
- response.statusCode = res.statusCode;
131
- response.statusMessage = res.statusMessage;
132
- response.headers = res.headers;
133
- response.body = data;
134
- if (response.body && response.headers['content-type'] && response.headers['content-type'].includes('application/json'))
135
- try {
136
- response.body = (parse) ? parse(response.body) : JSON.parse(response.body);
137
- log.debug('response.parse JSON');
138
- }
139
- catch (error) {
140
- console.error(error);
141
- }
142
- if (response.statusCode >= 200 && response.statusCode < 400)
143
- resolve(response);
144
- else {
145
- log.debug('response.error %O', response);
146
- reject(response);
147
- }
148
- });
149
- }
150
- });
151
- if (body)
152
- req.write(body);
153
- if (file) {
154
- const crlf = '\r\n';
155
- const boundary = `--${Math.random().toString(16)}`;
156
- const delimeter = `${crlf}--${boundary}`;
157
- const headers = [`Content-Disposition: form-data; name="file"; filename="${basename(file)}"${crlf}`];
158
- const multipartBody = Buffer.concat([
159
- Buffer.from(delimeter + crlf + headers.join('') + crlf),
160
- readFileSync(file),
161
- Buffer.from(`${delimeter}--`)
162
- ]);
163
- req.setHeader('Content-Type', 'multipart/form-data; boundary=' + boundary);
164
- req.setHeader('Content-Length', multipartBody.length);
165
- req.write(multipartBody);
166
- }
167
- req.on('error', function (e) {
168
- log.timeEnd(url, 'response.error %O', e);
169
- reject(e);
170
- });
171
- log.time(url);
172
- req.end();
173
- });
174
- }
175
-
176
- export { request as default, querystringify, request, setMock };
package/lib/index.js DELETED
@@ -1,204 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- var http = require('http');
6
- var https = require('https');
7
- var url = require('url');
8
- var fs = require('fs');
9
- var path = require('path');
10
- var logger = require('@faasjs/logger');
11
-
12
- function _interopNamespace(e) {
13
- if (e && e.__esModule) return e;
14
- var n = Object.create(null);
15
- if (e) {
16
- Object.keys(e).forEach(function (k) {
17
- if (k !== 'default') {
18
- var d = Object.getOwnPropertyDescriptor(e, k);
19
- Object.defineProperty(n, k, d.get ? d : {
20
- enumerable: true,
21
- get: function () { return e[k]; }
22
- });
23
- }
24
- });
25
- }
26
- n["default"] = e;
27
- return Object.freeze(n);
28
- }
29
-
30
- var http__namespace = /*#__PURE__*/_interopNamespace(http);
31
- var https__namespace = /*#__PURE__*/_interopNamespace(https);
32
-
33
- let mock = null;
34
- /**
35
- * 设置模拟请求
36
- * @param handler {function | null} 模拟函数,若设置为 null 则表示清除模拟函数
37
- * @example setMock(async (url, options) => Promise.resolve({ headers: {}, statusCode: 200, body: { data: 'ok' } }))
38
- */
39
- function setMock(handler) {
40
- mock = handler;
41
- }
42
- function querystringify(obj) {
43
- const pairs = [];
44
- let value;
45
- let key;
46
- for (key in obj) {
47
- if (Object.prototype.hasOwnProperty.call(obj, key)) {
48
- value = obj[key];
49
- if (!value && (value === null || value === undefined || isNaN(value))) {
50
- value = '';
51
- }
52
- key = encodeURIComponent(key);
53
- value = encodeURIComponent(value);
54
- if (key === null || value === null)
55
- continue;
56
- pairs.push(key + '=' + value);
57
- }
58
- }
59
- return pairs.length ? pairs.join('&') : '';
60
- }
61
- /**
62
- * 发起网络请求
63
- * @param {string} url 请求路径或完整网址
64
- * @param {object=} [options={}] 参数和配置
65
- * @param {string} [options.methd=GET] 请求方法
66
- * @param {object} [options.query={}] 请求参数,放置于 path 后,若需放置在 body 中,请使用 body 参数
67
- * @param {object} [options.headers={}] 请求头
68
- * @param {object=} options.body 请求体
69
- * @param {number=} options.timeout 最长耗时,单位为毫秒
70
- * @param {string=} options.auth HTTP 认证头,格式为 user:password
71
- * @param {string=} options.file 上传文件的完整路径
72
- * @param {WritableStream=} options.downloadStream 下载流,用于直接将响应内容保存到本地文件
73
- * @param {Buffer=} options.pfx pfx
74
- * @param {string=} options.passphrase passphrase
75
- * @param {boolean=} options.agent agent
76
- * @param {parse=} options.parse body 解析器,默认为 JSON.parse
77
- *
78
- * @returns {promise}
79
- * @url https://faasjs.com/doc/request.html
80
- */
81
- async function request(url$1, { headers, method, query, body, timeout, auth, file, downloadStream, pfx, passphrase, agent, parse } = {
82
- headers: {},
83
- query: {}
84
- }) {
85
- const log = new logger.Logger('request');
86
- if (mock)
87
- return mock(url$1, {
88
- headers,
89
- method,
90
- query,
91
- body
92
- });
93
- // 序列化 query
94
- if (query) {
95
- if (!url$1.includes('?'))
96
- url$1 += '?';
97
- else if (!url$1.endsWith('?'))
98
- url$1 += '&';
99
- url$1 += querystringify(query);
100
- }
101
- // 处理 URL 并生成 options
102
- const uri = new url.URL(url$1);
103
- const protocol = uri.protocol === 'https:' ? https__namespace : http__namespace;
104
- if (!uri.protocol)
105
- throw Error('Unkonw protocol');
106
- const options = {
107
- headers: {},
108
- host: uri.host ? uri.host.replace(/:[0-9]+$/, '') : uri.host,
109
- method: method ? method.toUpperCase() : 'GET',
110
- path: uri.pathname + uri.search,
111
- query: {},
112
- port: uri.port,
113
- timeout,
114
- auth,
115
- pfx,
116
- passphrase,
117
- agent
118
- };
119
- // 处理 headers
120
- for (const key in headers)
121
- if (typeof headers[key] !== 'undefined' && headers[key] !== null)
122
- options.headers[key] = headers[key];
123
- // 序列化 body
124
- if (body && typeof body !== 'string')
125
- if (options.headers['Content-Type'] &&
126
- options.headers['Content-Type'].toString().includes('application/x-www-form-urlencoded'))
127
- body = querystringify(body);
128
- else
129
- body = JSON.stringify(body);
130
- if (body && !options.headers['Content-Length'])
131
- options.headers['Content-Length'] = Buffer.byteLength(body);
132
- return await new Promise(function (resolve, reject) {
133
- log.debug('request %O', {
134
- ...options,
135
- body
136
- });
137
- const req = protocol.request(options, function (res) {
138
- if (downloadStream) {
139
- res.pipe(downloadStream);
140
- downloadStream.on('finish', function () {
141
- resolve(undefined);
142
- });
143
- }
144
- else {
145
- const raw = [];
146
- res.on('data', (chunk) => {
147
- raw.push(chunk);
148
- });
149
- res.on('end', () => {
150
- const data = Buffer.concat(raw).toString();
151
- log.timeEnd(url$1, 'response %s %s %s', res.statusCode, res.headers['content-type'], data);
152
- const response = Object.create(null);
153
- response.request = options;
154
- response.request.body = body;
155
- response.statusCode = res.statusCode;
156
- response.statusMessage = res.statusMessage;
157
- response.headers = res.headers;
158
- response.body = data;
159
- if (response.body && response.headers['content-type'] && response.headers['content-type'].includes('application/json'))
160
- try {
161
- response.body = (parse) ? parse(response.body) : JSON.parse(response.body);
162
- log.debug('response.parse JSON');
163
- }
164
- catch (error) {
165
- console.error(error);
166
- }
167
- if (response.statusCode >= 200 && response.statusCode < 400)
168
- resolve(response);
169
- else {
170
- log.debug('response.error %O', response);
171
- reject(response);
172
- }
173
- });
174
- }
175
- });
176
- if (body)
177
- req.write(body);
178
- if (file) {
179
- const crlf = '\r\n';
180
- const boundary = `--${Math.random().toString(16)}`;
181
- const delimeter = `${crlf}--${boundary}`;
182
- const headers = [`Content-Disposition: form-data; name="file"; filename="${path.basename(file)}"${crlf}`];
183
- const multipartBody = Buffer.concat([
184
- Buffer.from(delimeter + crlf + headers.join('') + crlf),
185
- fs.readFileSync(file),
186
- Buffer.from(`${delimeter}--`)
187
- ]);
188
- req.setHeader('Content-Type', 'multipart/form-data; boundary=' + boundary);
189
- req.setHeader('Content-Length', multipartBody.length);
190
- req.write(multipartBody);
191
- }
192
- req.on('error', function (e) {
193
- log.timeEnd(url$1, 'response.error %O', e);
194
- reject(e);
195
- });
196
- log.time(url$1);
197
- req.end();
198
- });
199
- }
200
-
201
- exports["default"] = request;
202
- exports.querystringify = querystringify;
203
- exports.request = request;
204
- exports.setMock = setMock;