@faasjs/request 0.0.2-beta.8 → 0.0.3-beta.1

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
@@ -1,9 +1,157 @@
1
1
  # @faasjs/request
2
2
 
3
- 网络请求库
4
-
5
- [![License: MIT](https://img.shields.io/npm/l/@faasjs/request.svg)](https://github.com/faasjs/faasjs/blob/master/packages/faasjs/request/LICENSE)
3
+ [![License: MIT](https://img.shields.io/npm/l/@faasjs/request.svg)](https://github.com/faasjs/faasjs/blob/main/packages/faasjs/request/LICENSE)
6
4
  [![NPM Stable Version](https://img.shields.io/npm/v/@faasjs/request/stable.svg)](https://www.npmjs.com/package/@faasjs/request)
7
5
  [![NPM Beta Version](https://img.shields.io/npm/v/@faasjs/request/beta.svg)](https://www.npmjs.com/package/@faasjs/request)
8
6
 
7
+ FaasJS's request module.
8
+
9
+ ## Install
10
+
11
+ npm install @faasjs/request
12
+
13
+ ## Modules
14
+
15
+ ### Type Aliases
16
+
17
+ - [Request](#request)
18
+ - [RequestOptions](#requestoptions)
19
+ - [Response](#response)
20
+
21
+ ### Functions
22
+
23
+ - [querystringify](#querystringify)
24
+ - [request](#request-1)
25
+ - [setMock](#setmock)
26
+
27
+ ## Type Aliases
28
+
29
+ ### Request
30
+
31
+ Ƭ **Request**: `Object`
32
+
33
+ #### Type declaration
34
+
35
+ | Name | Type |
36
+ | :------ | :------ |
37
+ | `body?` | { `[key: string]`: `any`; } |
38
+ | `headers?` | `http.OutgoingHttpHeaders` |
39
+ | `host?` | `string` |
40
+ | `method?` | `string` |
41
+ | `path?` | `string` |
42
+ | `query?` | `http.OutgoingHttpHeaders` |
43
+
44
+ ___
45
+
46
+ ### RequestOptions
47
+
48
+ Ƭ **RequestOptions**: `Object`
49
+
50
+ #### Type declaration
51
+
52
+ | Name | Type | Description |
53
+ | :------ | :------ | :------ |
54
+ | `agent?` | `boolean` | - |
55
+ | `auth?` | `string` | The authentication credentials to use for the request. Format: `username:password` |
56
+ | `body?` | { `[key: string]`: `any`; } \| `string` | - |
57
+ | `downloadStream?` | `NodeJS.WritableStream` | Create a write stream to download a file. |
58
+ | `file?` | `string` | Path of uploading a file to the server. |
59
+ | `headers?` | `http.OutgoingHttpHeaders` | - |
60
+ | `logger?` | `Logger` | - |
61
+ | `method?` | `string` | The HTTP method to use when making the request. Defaults to GET. |
62
+ | `parse?` | (`body`: `string`) => `any` | Body parser. Defaults to `JSON.parse`. |
63
+ | `passphrase?` | `string` | - |
64
+ | `pfx?` | `Buffer` | - |
65
+ | `query?` | { `[key: string]`: `any`; } | - |
66
+ | `timeout?` | `number` | - |
67
+
68
+ ___
69
+
70
+ ### Response
71
+
72
+ Ƭ **Response**<`T`\>: `Object`
73
+
74
+ #### Type parameters
75
+
76
+ | Name | Type |
77
+ | :------ | :------ |
78
+ | `T` | `any` |
79
+
80
+ #### Type declaration
81
+
82
+ | Name | Type |
83
+ | :------ | :------ |
84
+ | `body` | `T` |
85
+ | `headers` | `http.OutgoingHttpHeaders` |
86
+ | `request?` | [`Request`](#request) |
87
+ | `statusCode?` | `number` |
88
+ | `statusMessage?` | `string` |
89
+
90
+ ## Functions
91
+
92
+ ### querystringify
93
+
94
+ ▸ **querystringify**(`obj`): `string`
95
+
96
+ #### Parameters
97
+
98
+ | Name | Type |
99
+ | :------ | :------ |
100
+ | `obj` | `any` |
101
+
102
+ #### Returns
103
+
104
+ `string`
105
+
106
+ ___
107
+
108
+ ### request
109
+
110
+ ▸ **request**<`T`\>(`url`, `options?`): `Promise`<[`Response`](#response)<`T`\>\>
111
+
112
+ Request
113
+
114
+ **`Url`**
115
+
9
116
  https://faasjs.com/doc/request.html
117
+
118
+ #### Type parameters
119
+
120
+ | Name | Type |
121
+ | :------ | :------ |
122
+ | `T` | `any` |
123
+
124
+ #### Parameters
125
+
126
+ | Name | Type | Description |
127
+ | :------ | :------ | :------ |
128
+ | `url` | `string` | Url |
129
+ | `options?` | [`RequestOptions`](#requestoptions) | Options |
130
+
131
+ #### Returns
132
+
133
+ `Promise`<[`Response`](#response)<`T`\>\>
134
+
135
+ ___
136
+
137
+ ### setMock
138
+
139
+ ▸ **setMock**(`handler`): `void`
140
+
141
+ Mock requests
142
+
143
+ **`Example`**
144
+
145
+ ```ts
146
+ setMock(async (url, options) => Promise.resolve({ headers: {}, statusCode: 200, body: { data: 'ok' } }))
147
+ ```
148
+
149
+ #### Parameters
150
+
151
+ | Name | Type | Description |
152
+ | :------ | :------ | :------ |
153
+ | `handler` | `Mock` | {function \| null} null to disable mock |
154
+
155
+ #### Returns
156
+
157
+ `void`
@@ -0,0 +1,87 @@
1
+ import * as http from 'http';
2
+ import { Logger } from '@faasjs/logger';
3
+
4
+ type Request = {
5
+ headers?: http.OutgoingHttpHeaders;
6
+ method?: string;
7
+ host?: string;
8
+ path?: string;
9
+ query?: http.OutgoingHttpHeaders;
10
+ body?: {
11
+ [key: string]: any;
12
+ };
13
+ };
14
+ type Response<T = any> = {
15
+ request?: Request;
16
+ statusCode?: number;
17
+ statusMessage?: string;
18
+ headers: http.OutgoingHttpHeaders;
19
+ body: T;
20
+ };
21
+ type RequestOptions = {
22
+ headers?: http.OutgoingHttpHeaders;
23
+ /**
24
+ * The HTTP method to use when making the request. Defaults to GET.
25
+ */
26
+ method?: string;
27
+ query?: {
28
+ [key: string]: any;
29
+ };
30
+ body?: {
31
+ [key: string]: any;
32
+ } | string;
33
+ timeout?: number;
34
+ /**
35
+ * The authentication credentials to use for the request.
36
+ *
37
+ * Format: `username:password`
38
+ */
39
+ auth?: string;
40
+ /**
41
+ * Path of uploading a file to the server.
42
+ */
43
+ file?: string;
44
+ /**
45
+ * Create a write stream to download a file.
46
+ */
47
+ downloadStream?: NodeJS.WritableStream;
48
+ pfx?: Buffer;
49
+ passphrase?: string;
50
+ agent?: boolean;
51
+ /**
52
+ * Body parser. Defaults to `JSON.parse`.
53
+ */
54
+ parse?: (body: string) => any;
55
+ logger?: Logger;
56
+ };
57
+ type Mock = (url: string, options: RequestOptions) => Promise<Response>;
58
+ /**
59
+ * Mock requests
60
+ * @param handler {function | null} null to disable mock
61
+ * @example setMock(async (url, options) => Promise.resolve({ headers: {}, statusCode: 200, body: { data: 'ok' } }))
62
+ */
63
+ declare function setMock(handler: Mock | null): void;
64
+ declare function querystringify(obj: any): string;
65
+ /**
66
+ * Request
67
+ * @param {string} url Url
68
+ * @param {object=} [options={}] Options
69
+ * @param {string} [options.method=GET] Method
70
+ * @param {object} [options.query={}] Query
71
+ * @param {object} [options.headers={}] Headers
72
+ * @param {object=} options.body Body
73
+ * @param {number=} options.timeout Timeout
74
+ * @param {string=} options.auth Auth, format: user:password
75
+ * @param {string=} options.file Upload file path
76
+ * @param {WritableStream=} options.downloadStream Download stream
77
+ * @param {Buffer=} options.pfx pfx
78
+ * @param {string=} options.passphrase passphrase
79
+ * @param {boolean=} options.agent agent
80
+ * @param {parse=} options.parse body parser, default is JSON.parse
81
+ *
82
+ * @returns {promise}
83
+ * @url https://faasjs.com/doc/request.html
84
+ */
85
+ declare function request<T = any>(url: string, { headers, method, query, body, timeout, auth, file, downloadStream, pfx, passphrase, agent, parse, logger, }?: RequestOptions): Promise<Response<T>>;
86
+
87
+ export { Request, RequestOptions, Response, querystringify, request, setMock };
package/dist/index.js ADDED
@@ -0,0 +1,192 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
+ mod
23
+ ));
24
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
25
+
26
+ // src/index.ts
27
+ var src_exports = {};
28
+ __export(src_exports, {
29
+ querystringify: () => querystringify,
30
+ request: () => request,
31
+ setMock: () => setMock
32
+ });
33
+ module.exports = __toCommonJS(src_exports);
34
+ var http = __toESM(require("http"));
35
+ var https = __toESM(require("https"));
36
+ var import_url = require("url");
37
+ var import_fs = require("fs");
38
+ var import_path = require("path");
39
+ var import_logger = require("@faasjs/logger");
40
+ var mock = null;
41
+ function setMock(handler) {
42
+ mock = handler;
43
+ }
44
+ function querystringify(obj) {
45
+ const pairs = [];
46
+ let value;
47
+ let key;
48
+ for (key in obj) {
49
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
50
+ value = obj[key];
51
+ if (!value && (value === null || value === void 0 || isNaN(value))) {
52
+ value = "";
53
+ }
54
+ key = encodeURIComponent(key);
55
+ value = encodeURIComponent(value);
56
+ if (key === null || value === null)
57
+ continue;
58
+ pairs.push(key + "=" + value);
59
+ }
60
+ }
61
+ return pairs.length ? pairs.join("&") : "";
62
+ }
63
+ async function request(url, {
64
+ headers,
65
+ method,
66
+ query,
67
+ body,
68
+ timeout,
69
+ auth,
70
+ file,
71
+ downloadStream,
72
+ pfx,
73
+ passphrase,
74
+ agent,
75
+ parse,
76
+ logger
77
+ } = { headers: {} }) {
78
+ if (!logger)
79
+ logger = new import_logger.Logger("request");
80
+ if (mock)
81
+ return mock(url, {
82
+ headers,
83
+ method,
84
+ query,
85
+ body
86
+ });
87
+ if (query) {
88
+ if (!url.includes("?"))
89
+ url += "?";
90
+ else if (!url.endsWith("?"))
91
+ url += "&";
92
+ url += querystringify(query);
93
+ }
94
+ const uri = new import_url.URL(url);
95
+ const protocol = uri.protocol === "https:" ? https : http;
96
+ if (!uri.protocol)
97
+ throw Error("Unknown protocol");
98
+ const options = {
99
+ headers: {},
100
+ host: uri.host ? uri.host.replace(/:[0-9]+$/, "") : uri.host,
101
+ method: method ? method.toUpperCase() : "GET",
102
+ path: uri.pathname + uri.search,
103
+ port: uri.port,
104
+ timeout,
105
+ auth,
106
+ pfx,
107
+ passphrase,
108
+ agent
109
+ };
110
+ for (const key in headers)
111
+ if (typeof headers[key] !== "undefined" && headers[key] !== null)
112
+ options.headers[key] = headers[key];
113
+ if (body && typeof body !== "string")
114
+ if (options.headers["Content-Type"] && options.headers["Content-Type"].toString().includes("application/x-www-form-urlencoded"))
115
+ body = querystringify(body);
116
+ else
117
+ body = JSON.stringify(body);
118
+ if (body && !options.headers["Content-Length"])
119
+ options.headers["Content-Length"] = Buffer.byteLength(body);
120
+ return await new Promise(function(resolve, reject) {
121
+ logger.debug("request %j", {
122
+ ...options,
123
+ body
124
+ });
125
+ const req = protocol.request(options, function(res) {
126
+ if (downloadStream) {
127
+ res.pipe(downloadStream);
128
+ downloadStream.on("finish", function() {
129
+ resolve(void 0);
130
+ });
131
+ } else {
132
+ const raw = [];
133
+ res.on("data", (chunk) => {
134
+ raw.push(chunk);
135
+ });
136
+ res.on("end", () => {
137
+ const data = Buffer.concat(raw).toString();
138
+ logger.timeEnd(url, "response %s %s %s", res.statusCode, res.headers["content-type"], data);
139
+ const response = /* @__PURE__ */ Object.create(null);
140
+ response.request = options;
141
+ response.request.body = body;
142
+ response.statusCode = res.statusCode;
143
+ response.statusMessage = res.statusMessage;
144
+ response.headers = res.headers;
145
+ response.body = data;
146
+ if (response.body && response.headers["content-type"] && response.headers["content-type"].includes("application/json"))
147
+ try {
148
+ response.body = parse ? parse(response.body) : JSON.parse(response.body);
149
+ logger.debug("response.parse JSON");
150
+ } catch (error) {
151
+ console.warn("response plain body", response.body);
152
+ console.error(error);
153
+ }
154
+ if (response.statusCode >= 200 && response.statusCode < 400)
155
+ resolve(response);
156
+ else {
157
+ logger.debug("response.error %j", response);
158
+ reject(response);
159
+ }
160
+ });
161
+ }
162
+ });
163
+ if (body)
164
+ req.write(body);
165
+ if (file) {
166
+ const crlf = "\r\n";
167
+ const boundary = `--${Math.random().toString(16)}`;
168
+ const delimiter = `${crlf}--${boundary}`;
169
+ const headers2 = [`Content-Disposition: form-data; name="file"; filename="${(0, import_path.basename)(file)}"${crlf}`];
170
+ const multipartBody = Buffer.concat([
171
+ Buffer.from(delimiter + crlf + headers2.join("") + crlf),
172
+ (0, import_fs.readFileSync)(file),
173
+ Buffer.from(`${delimiter}--`)
174
+ ]);
175
+ req.setHeader("Content-Type", "multipart/form-data; boundary=" + boundary);
176
+ req.setHeader("Content-Length", multipartBody.length);
177
+ req.write(multipartBody);
178
+ }
179
+ req.on("error", function(e) {
180
+ logger.timeEnd(url, "response.error %j", e);
181
+ reject(e);
182
+ });
183
+ logger.time(url);
184
+ req.end();
185
+ });
186
+ }
187
+ // Annotate the CommonJS export names for ESM import in node:
188
+ 0 && (module.exports = {
189
+ querystringify,
190
+ request,
191
+ setMock
192
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,159 @@
1
+ // src/index.ts
2
+ import * as http from "http";
3
+ import * as https from "https";
4
+ import { URL } from "url";
5
+ import { readFileSync } from "fs";
6
+ import { basename } from "path";
7
+ import { Logger } from "@faasjs/logger";
8
+ var mock = null;
9
+ function setMock(handler) {
10
+ mock = handler;
11
+ }
12
+ function querystringify(obj) {
13
+ const pairs = [];
14
+ let value;
15
+ let key;
16
+ for (key in obj) {
17
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
18
+ value = obj[key];
19
+ if (!value && (value === null || value === void 0 || isNaN(value))) {
20
+ value = "";
21
+ }
22
+ key = encodeURIComponent(key);
23
+ value = encodeURIComponent(value);
24
+ if (key === null || value === null)
25
+ continue;
26
+ pairs.push(key + "=" + value);
27
+ }
28
+ }
29
+ return pairs.length ? pairs.join("&") : "";
30
+ }
31
+ async function request(url, {
32
+ headers,
33
+ method,
34
+ query,
35
+ body,
36
+ timeout,
37
+ auth,
38
+ file,
39
+ downloadStream,
40
+ pfx,
41
+ passphrase,
42
+ agent,
43
+ parse,
44
+ logger
45
+ } = { headers: {} }) {
46
+ if (!logger)
47
+ logger = new Logger("request");
48
+ if (mock)
49
+ return mock(url, {
50
+ headers,
51
+ method,
52
+ query,
53
+ body
54
+ });
55
+ if (query) {
56
+ if (!url.includes("?"))
57
+ url += "?";
58
+ else if (!url.endsWith("?"))
59
+ url += "&";
60
+ url += querystringify(query);
61
+ }
62
+ const uri = new URL(url);
63
+ const protocol = uri.protocol === "https:" ? https : http;
64
+ if (!uri.protocol)
65
+ throw Error("Unknown protocol");
66
+ const options = {
67
+ headers: {},
68
+ host: uri.host ? uri.host.replace(/:[0-9]+$/, "") : uri.host,
69
+ method: method ? method.toUpperCase() : "GET",
70
+ path: uri.pathname + uri.search,
71
+ port: uri.port,
72
+ timeout,
73
+ auth,
74
+ pfx,
75
+ passphrase,
76
+ agent
77
+ };
78
+ for (const key in headers)
79
+ if (typeof headers[key] !== "undefined" && headers[key] !== null)
80
+ options.headers[key] = headers[key];
81
+ if (body && typeof body !== "string")
82
+ if (options.headers["Content-Type"] && options.headers["Content-Type"].toString().includes("application/x-www-form-urlencoded"))
83
+ body = querystringify(body);
84
+ else
85
+ body = JSON.stringify(body);
86
+ if (body && !options.headers["Content-Length"])
87
+ options.headers["Content-Length"] = Buffer.byteLength(body);
88
+ return await new Promise(function(resolve, reject) {
89
+ logger.debug("request %j", {
90
+ ...options,
91
+ body
92
+ });
93
+ const req = protocol.request(options, function(res) {
94
+ if (downloadStream) {
95
+ res.pipe(downloadStream);
96
+ downloadStream.on("finish", function() {
97
+ resolve(void 0);
98
+ });
99
+ } else {
100
+ const raw = [];
101
+ res.on("data", (chunk) => {
102
+ raw.push(chunk);
103
+ });
104
+ res.on("end", () => {
105
+ const data = Buffer.concat(raw).toString();
106
+ logger.timeEnd(url, "response %s %s %s", res.statusCode, res.headers["content-type"], data);
107
+ const response = /* @__PURE__ */ Object.create(null);
108
+ response.request = options;
109
+ response.request.body = body;
110
+ response.statusCode = res.statusCode;
111
+ response.statusMessage = res.statusMessage;
112
+ response.headers = res.headers;
113
+ response.body = data;
114
+ if (response.body && response.headers["content-type"] && response.headers["content-type"].includes("application/json"))
115
+ try {
116
+ response.body = parse ? parse(response.body) : JSON.parse(response.body);
117
+ logger.debug("response.parse JSON");
118
+ } catch (error) {
119
+ console.warn("response plain body", response.body);
120
+ console.error(error);
121
+ }
122
+ if (response.statusCode >= 200 && response.statusCode < 400)
123
+ resolve(response);
124
+ else {
125
+ logger.debug("response.error %j", response);
126
+ reject(response);
127
+ }
128
+ });
129
+ }
130
+ });
131
+ if (body)
132
+ req.write(body);
133
+ if (file) {
134
+ const crlf = "\r\n";
135
+ const boundary = `--${Math.random().toString(16)}`;
136
+ const delimiter = `${crlf}--${boundary}`;
137
+ const headers2 = [`Content-Disposition: form-data; name="file"; filename="${basename(file)}"${crlf}`];
138
+ const multipartBody = Buffer.concat([
139
+ Buffer.from(delimiter + crlf + headers2.join("") + crlf),
140
+ readFileSync(file),
141
+ Buffer.from(`${delimiter}--`)
142
+ ]);
143
+ req.setHeader("Content-Type", "multipart/form-data; boundary=" + boundary);
144
+ req.setHeader("Content-Length", multipartBody.length);
145
+ req.write(multipartBody);
146
+ }
147
+ req.on("error", function(e) {
148
+ logger.timeEnd(url, "response.error %j", e);
149
+ reject(e);
150
+ });
151
+ logger.time(url);
152
+ req.end();
153
+ });
154
+ }
155
+ export {
156
+ querystringify,
157
+ request,
158
+ setMock
159
+ };
package/package.json CHANGED
@@ -1,26 +1,31 @@
1
1
  {
2
2
  "name": "@faasjs/request",
3
- "version": "0.0.2-beta.8",
3
+ "version": "0.0.3-beta.1",
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
+ "homepage": "https://faasjs.com/doc/request",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/faasjs/faasjs.git",
11
+ "directory": "packages/request"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/faasjs/faasjs/issues"
15
+ },
16
+ "funding": "https://github.com/sponsors/faasjs",
8
17
  "scripts": {
9
- "prepack": "rm -rf ./lib && rollup -c && mv lib/*/src/* lib/"
18
+ "build": "tsup-node src/index.ts --format esm,cjs",
19
+ "build:types": "tsup-node src/index.ts --dts-only"
10
20
  },
11
21
  "files": [
12
- "lib"
22
+ "dist"
13
23
  ],
14
24
  "dependencies": {
15
- "@faasjs/logger": "^0.0.2-beta.2"
16
- },
17
- "devDependencies": {
18
- "@types/debug": "*",
19
- "@types/jest": "*",
20
- "@types/node": "*",
21
- "rollup": "*",
22
- "rollup-plugin-typescript2": "*",
23
- "typescript": "*"
25
+ "@faasjs/logger": "^0.0.3-beta.1"
24
26
  },
25
- "gitHead": "dd17bdcc35c0b619483a3c842bc41ab4998786a5"
27
+ "engines": {
28
+ "npm": ">=8.0.0",
29
+ "node": ">=16.0.0"
30
+ }
26
31
  }
package/lib/index.d.ts DELETED
@@ -1,46 +0,0 @@
1
- /// <reference types="node" />
2
- import * as http from 'http';
3
- export interface Request {
4
- headers?: http.OutgoingHttpHeaders;
5
- method?: string;
6
- host?: string;
7
- path?: string;
8
- query?: http.OutgoingHttpHeaders;
9
- body?: any;
10
- }
11
- export interface Response {
12
- request?: Request;
13
- statusCode?: number;
14
- statusMessage?: string;
15
- headers: http.OutgoingHttpHeaders;
16
- body: any;
17
- }
18
- export interface RequestOptions {
19
- headers?: http.OutgoingHttpHeaders;
20
- method?: string;
21
- query?: http.OutgoingHttpHeaders;
22
- body?: any;
23
- timeout?: number;
24
- auth?: string;
25
- }
26
- declare type Mock = (url: string, options: RequestOptions) => Promise<Response>;
27
- /**
28
- * 设置模拟请求
29
- * @param handler {function | null} 模拟函数,若设置为 null 则表示清除模拟函数
30
- */
31
- export declare function setMock(handler: Mock | null): void;
32
- /**
33
- * 发起网络请求
34
- * @param {string} url 请求路径或完整网址
35
- * @param {object=} [options={}] 参数和配置
36
- * @param {string} [options.methd=GET] 请求方法
37
- * @param {object} [options.query={}] 请求参数,放置于 path 后,若需放置在 body 中,请使用 body 参数
38
- * @param {object} [options.headers={}] 请求头
39
- * @param {object=} options.body 请求体
40
- * @param {number=} options.timeout 最长耗时,单位为毫秒
41
- * @param {string=} options.auth HTTP 认证头,格式为 user:password
42
- *
43
- * @returns {promise}
44
- */
45
- export default function (url: string, { headers, method, query, body, timeout, auth }?: RequestOptions): Promise<Response>;
46
- export {};
package/lib/index.es.js DELETED
@@ -1,131 +0,0 @@
1
- import * as http from 'http';
2
- import * as https from 'https';
3
- import { stringify } from 'querystring';
4
- import { parse } from 'url';
5
- import Logger from '@faasjs/logger';
6
-
7
- const log = new Logger('request');
8
- let mock = null;
9
- /**
10
- * 设置模拟请求
11
- * @param handler {function | null} 模拟函数,若设置为 null 则表示清除模拟函数
12
- */
13
- function setMock(handler) {
14
- mock = handler;
15
- }
16
- /**
17
- * 发起网络请求
18
- * @param {string} url 请求路径或完整网址
19
- * @param {object=} [options={}] 参数和配置
20
- * @param {string} [options.methd=GET] 请求方法
21
- * @param {object} [options.query={}] 请求参数,放置于 path 后,若需放置在 body 中,请使用 body 参数
22
- * @param {object} [options.headers={}] 请求头
23
- * @param {object=} options.body 请求体
24
- * @param {number=} options.timeout 最长耗时,单位为毫秒
25
- * @param {string=} options.auth HTTP 认证头,格式为 user:password
26
- *
27
- * @returns {promise}
28
- */
29
- async function index (url, { headers, method, query, body, timeout, auth } = {
30
- headers: {},
31
- query: {},
32
- }) {
33
- log.debug('request %s %o', url, {
34
- body,
35
- headers,
36
- method,
37
- query,
38
- });
39
- if (mock)
40
- return mock(url, {
41
- headers,
42
- method,
43
- query,
44
- body
45
- });
46
- // 序列化 query
47
- if (query) {
48
- if (!url.includes('?'))
49
- url += '?';
50
- else if (!url.endsWith('?'))
51
- url += '&';
52
- url += stringify(query);
53
- }
54
- // 处理 URL 并生成 options
55
- const uri = parse(url);
56
- const protocol = uri.protocol === 'https:' ? https : http;
57
- if (!uri.protocol)
58
- throw Error('Unkonw protocol');
59
- const options = {
60
- headers: {},
61
- host: uri.host ? uri.host.replace(/:[0-9]+$/, '') : uri.host,
62
- method: method ? method.toUpperCase() : 'GET',
63
- path: uri.path,
64
- query: {},
65
- port: uri.port,
66
- timeout,
67
- auth
68
- };
69
- // 处理 headers
70
- for (const key in headers)
71
- if (typeof headers[key] !== 'undefined' && headers[key] !== null)
72
- options.headers[key] = headers[key];
73
- // 序列化 body
74
- if (body && typeof body !== 'string')
75
- if (options.headers['Content-Type'] &&
76
- options.headers['Content-Type'].toString().includes('application/x-www-form-urlencoded')) {
77
- body = stringify(body);
78
- }
79
- else {
80
- body = JSON.stringify(body);
81
- }
82
- if (body && !options.headers['Content-Length'])
83
- options.headers['Content-Length'] = Buffer.byteLength(body);
84
- // eslint-disable-next-line @typescript-eslint/typedef
85
- return new Promise(function (resolve, reject) {
86
- // 包裹请求
87
- const req = protocol.request(options, function (res) {
88
- const raw = [];
89
- res.on('data', (chunk) => {
90
- raw.push(chunk);
91
- });
92
- res.on('end', () => {
93
- const data = Buffer.concat(raw).toString();
94
- log.timeEnd(url, 'response %s %s %s', res.statusCode, res.headers['content-type'], data);
95
- const response = Object.create(null);
96
- response.request = options;
97
- response.request.body = body;
98
- response.statusCode = res.statusCode;
99
- response.statusMessage = res.statusMessage;
100
- response.headers = res.headers;
101
- response.body = data;
102
- if (response.body && response.headers['content-type'] && response.headers['content-type'].includes('application/json'))
103
- try {
104
- response.body = JSON.parse(response.body);
105
- log.debug('response.parse JSON');
106
- }
107
- catch (error) {
108
- console.error(error);
109
- }
110
- if (response.statusCode >= 200 && response.statusCode < 400)
111
- resolve(response);
112
- else {
113
- log.debug('response.error %o', response);
114
- reject(response);
115
- }
116
- });
117
- });
118
- if (body)
119
- req.write(body);
120
- req.on('error', function (e) {
121
- log.timeEnd(url, 'response.error %o', e);
122
- reject(e);
123
- });
124
- // 发送请求
125
- log.time(url);
126
- req.end();
127
- });
128
- }
129
-
130
- export default index;
131
- export { setMock };
package/lib/index.js DELETED
@@ -1,137 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
6
-
7
- var http = require('http');
8
- var https = require('https');
9
- var querystring = require('querystring');
10
- var URL = require('url');
11
- var Logger = _interopDefault(require('@faasjs/logger'));
12
-
13
- const log = new Logger('request');
14
- let mock = null;
15
- /**
16
- * 设置模拟请求
17
- * @param handler {function | null} 模拟函数,若设置为 null 则表示清除模拟函数
18
- */
19
- function setMock(handler) {
20
- mock = handler;
21
- }
22
- /**
23
- * 发起网络请求
24
- * @param {string} url 请求路径或完整网址
25
- * @param {object=} [options={}] 参数和配置
26
- * @param {string} [options.methd=GET] 请求方法
27
- * @param {object} [options.query={}] 请求参数,放置于 path 后,若需放置在 body 中,请使用 body 参数
28
- * @param {object} [options.headers={}] 请求头
29
- * @param {object=} options.body 请求体
30
- * @param {number=} options.timeout 最长耗时,单位为毫秒
31
- * @param {string=} options.auth HTTP 认证头,格式为 user:password
32
- *
33
- * @returns {promise}
34
- */
35
- async function index (url, { headers, method, query, body, timeout, auth } = {
36
- headers: {},
37
- query: {},
38
- }) {
39
- log.debug('request %s %o', url, {
40
- body,
41
- headers,
42
- method,
43
- query,
44
- });
45
- if (mock)
46
- return mock(url, {
47
- headers,
48
- method,
49
- query,
50
- body
51
- });
52
- // 序列化 query
53
- if (query) {
54
- if (!url.includes('?'))
55
- url += '?';
56
- else if (!url.endsWith('?'))
57
- url += '&';
58
- url += querystring.stringify(query);
59
- }
60
- // 处理 URL 并生成 options
61
- const uri = URL.parse(url);
62
- const protocol = uri.protocol === 'https:' ? https : http;
63
- if (!uri.protocol)
64
- throw Error('Unkonw protocol');
65
- const options = {
66
- headers: {},
67
- host: uri.host ? uri.host.replace(/:[0-9]+$/, '') : uri.host,
68
- method: method ? method.toUpperCase() : 'GET',
69
- path: uri.path,
70
- query: {},
71
- port: uri.port,
72
- timeout,
73
- auth
74
- };
75
- // 处理 headers
76
- for (const key in headers)
77
- if (typeof headers[key] !== 'undefined' && headers[key] !== null)
78
- options.headers[key] = headers[key];
79
- // 序列化 body
80
- if (body && typeof body !== 'string')
81
- if (options.headers['Content-Type'] &&
82
- options.headers['Content-Type'].toString().includes('application/x-www-form-urlencoded')) {
83
- body = querystring.stringify(body);
84
- }
85
- else {
86
- body = JSON.stringify(body);
87
- }
88
- if (body && !options.headers['Content-Length'])
89
- options.headers['Content-Length'] = Buffer.byteLength(body);
90
- // eslint-disable-next-line @typescript-eslint/typedef
91
- return new Promise(function (resolve, reject) {
92
- // 包裹请求
93
- const req = protocol.request(options, function (res) {
94
- const raw = [];
95
- res.on('data', (chunk) => {
96
- raw.push(chunk);
97
- });
98
- res.on('end', () => {
99
- const data = Buffer.concat(raw).toString();
100
- log.timeEnd(url, 'response %s %s %s', res.statusCode, res.headers['content-type'], data);
101
- const response = Object.create(null);
102
- response.request = options;
103
- response.request.body = body;
104
- response.statusCode = res.statusCode;
105
- response.statusMessage = res.statusMessage;
106
- response.headers = res.headers;
107
- response.body = data;
108
- if (response.body && response.headers['content-type'] && response.headers['content-type'].includes('application/json'))
109
- try {
110
- response.body = JSON.parse(response.body);
111
- log.debug('response.parse JSON');
112
- }
113
- catch (error) {
114
- console.error(error);
115
- }
116
- if (response.statusCode >= 200 && response.statusCode < 400)
117
- resolve(response);
118
- else {
119
- log.debug('response.error %o', response);
120
- reject(response);
121
- }
122
- });
123
- });
124
- if (body)
125
- req.write(body);
126
- req.on('error', function (e) {
127
- log.timeEnd(url, 'response.error %o', e);
128
- reject(e);
129
- });
130
- // 发送请求
131
- log.time(url);
132
- req.end();
133
- });
134
- }
135
-
136
- exports.default = index;
137
- exports.setMock = setMock;