Compare commits

...

23 Commits

Author SHA1 Message Date
a32c372374 1.1.43 2019-11-21 17:32:31 +00:00
f98972d9fe fix(core): update 2019-11-21 17:32:30 +00:00
acebe6a381 1.1.42 2019-10-28 16:18:15 +01:00
7031504852 1.1.41 2019-10-27 14:41:49 +01:00
3010a1da9a fix(core): update 2019-10-27 14:41:48 +01:00
cdead33be4 1.1.40 2019-10-27 14:39:07 +01:00
5e23649702 fix(core): update 2019-10-27 14:39:06 +01:00
cc6bd5726a 1.1.39 2019-10-27 14:38:13 +01:00
f487584e80 fix(core): update 2019-10-27 14:38:12 +01:00
443bccd4c9 1.1.38 2019-10-27 14:36:18 +01:00
f359856b1d fix(core): update 2019-10-27 14:36:17 +01:00
bda04f124b 1.1.37 2019-10-27 14:32:27 +01:00
466187fd52 fix(core): update 2019-10-27 14:32:27 +01:00
d22504317e 1.1.36 2019-09-29 16:42:56 +02:00
6e31d84798 fix(core): update 2019-09-29 16:42:56 +02:00
36472b7306 1.1.35 2019-09-29 00:56:56 +02:00
e86f14b8d8 fix(core): update 2019-09-29 00:56:56 +02:00
2b9e7f6dd2 1.1.34 2019-09-29 00:43:37 +02:00
5e4afccf9c fix(core): update 2019-09-29 00:43:37 +02:00
3de7a1a210 1.1.33 2019-09-29 00:42:51 +02:00
bd2a5eedff fix(core): update 2019-09-29 00:42:51 +02:00
aa18357d75 1.1.32 2019-09-28 22:50:35 +02:00
9960aff219 fix(core): update 2019-09-28 22:50:35 +02:00
8 changed files with 137 additions and 138 deletions

View File

@ -3,14 +3,14 @@ image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
cache: cache:
paths: paths:
- .npmci_cache/ - .npmci_cache/
key: "$CI_BUILD_STAGE" key: '$CI_BUILD_STAGE'
stages: stages:
- security - security
- test - test
- release - release
- metadata - metadata
# ==================== # ====================
# security stage # security stage
@ -18,21 +18,23 @@ stages:
mirror: mirror:
stage: security stage: security
script: script:
- npmci git mirror - npmci git mirror
tags: tags:
- docker - lossless
- notpriv - docker
- notpriv
snyk: snyk:
image: registry.gitlab.com/hosttoday/ht-docker-node:snyk
stage: security stage: security
script: script:
- npmci npm prepare - npmci npm prepare
- npmci command npm install -g snyk
- npmci command npm install --ignore-scripts - npmci command npm install --ignore-scripts
- npmci command snyk test - npmci command snyk test
tags: tags:
- docker - lossless
- notpriv - docker
- notpriv
# ==================== # ====================
# test stage # test stage
@ -41,37 +43,40 @@ snyk:
testStable: testStable:
stage: test stage: test
script: script:
- npmci npm prepare - npmci npm prepare
- npmci node install stable - npmci node install stable
- npmci npm install - npmci npm install
- npmci npm test - npmci npm test
coverage: /\d+.?\d+?\%\s*coverage/ coverage: /\d+.?\d+?\%\s*coverage/
tags: tags:
- docker - lossless
- priv - docker
- priv
testBuild: testBuild:
stage: test stage: test
script: script:
- npmci npm prepare - npmci npm prepare
- npmci node install lts - npmci node install stable
- npmci npm install - npmci npm install
- npmci command npm run build - npmci command npm run build
coverage: /\d+.?\d+?\%\s*coverage/ coverage: /\d+.?\d+?\%\s*coverage/
tags: tags:
- docker - lossless
- notpriv - docker
- notpriv
release: release:
stage: release stage: release
script: script:
- npmci node install lts - npmci node install stable
- npmci npm publish - npmci npm publish
only: only:
- tags - tags
tags: tags:
- docker - lossless
- notpriv - docker
- notpriv
# ==================== # ====================
# metadata stage # metadata stage
@ -81,33 +86,35 @@ codequality:
allow_failure: true allow_failure: true
script: script:
- npmci command npm install -g tslint typescript - npmci command npm install -g tslint typescript
- npmci npm prepare
- npmci npm install - npmci npm install
- npmci command "tslint -c tslint.json ./ts/**/*.ts" - npmci command "tslint -c tslint.json ./ts/**/*.ts"
tags: tags:
- docker - lossless
- priv - docker
- priv
trigger: trigger:
stage: metadata stage: metadata
script: script:
- npmci trigger - npmci trigger
only: only:
- tags - tags
tags: tags:
- docker - lossless
- notpriv - docker
- notpriv
pages: pages:
image: hosttoday/ht-docker-dbase:npmci
services:
- docker:stable-dind
stage: metadata stage: metadata
script: script:
- npmci node install lts
- npmci command npm install -g @gitzone/tsdoc - npmci command npm install -g @gitzone/tsdoc
- npmci npm prepare - npmci npm prepare
- npmci npm install - npmci npm install
- npmci command tsdoc - npmci command tsdoc
tags: tags:
- lossless
- docker - docker
- notpriv - notpriv
only: only:
@ -115,5 +122,5 @@ pages:
artifacts: artifacts:
expire_in: 1 week expire_in: 1 week
paths: paths:
- public - public
allow_failure: true allow_failure: true

View File

@ -1,69 +0,0 @@
# @pushrocks/smartrequest
dropin replacement for request
## Availabililty and Links
* [npmjs.org (npm package)](https://www.npmjs.com/package/@pushrocks/smartrequest)
* [gitlab.com (source)](https://gitlab.com/pushrocks/smartrequest)
* [github.com (source mirror)](https://github.com/pushrocks/smartrequest)
* [docs (typedoc)](https://pushrocks.gitlab.io/smartrequest/)
## Status for master
[![build status](https://gitlab.com/pushrocks/smartrequest/badges/master/build.svg)](https://gitlab.com/pushrocks/smartrequest/commits/master)
[![coverage report](https://gitlab.com/pushrocks/smartrequest/badges/master/coverage.svg)](https://gitlab.com/pushrocks/smartrequest/commits/master)
[![npm downloads per month](https://img.shields.io/npm/dm/@pushrocks/smartrequest.svg)](https://www.npmjs.com/package/@pushrocks/smartrequest)
[![Known Vulnerabilities](https://snyk.io/test/npm/@pushrocks/smartrequest/badge.svg)](https://snyk.io/test/npm/@pushrocks/smartrequest)
[![TypeScript](https://img.shields.io/badge/TypeScript->=%203.x-blue.svg)](https://nodejs.org/dist/latest-v10.x/docs/api/)
[![node](https://img.shields.io/badge/node->=%2010.x.x-blue.svg)](https://nodejs.org/dist/latest-v10.x/docs/api/)
[![JavaScript Style Guide](https://img.shields.io/badge/code%20style-prettier-ff69b4.svg)](https://prettier.io/)
## Usage
Use TypeScript for best in class instellisense.
> note: smartrequest uses the **native** node request module under the hood (not the one from npm)
```javascript
import * as smartrequest from 'smartrequest'
// simple post
let options: smartrequest.ISmartRequestOptions = { // typed options
headers: {
"Content-Type": "application/json"
"Authorization": "Bearer token"
},
requestBody: {
key1: 'value1',
key2: 3
}
}
smartrequest.post('https://example.com', options).then(res => {
console.log(res.status)
console.log(res.body) // if json, body will be parsed automatically
}).catch(err => {
console.log(err)
})
// also available
smartrequest.get(...)
smartrequest.put(...)
smartrequest.del(...)
// streaming
smartrequest.get('https://example.com/bigfile.mp4', optionsArg, true).then(res => { // third arg = true signals streaming
console.log(res.status)
res.on('data', data => {
// do something with the data chunk here
}
res.on('end', () => {
// do something when things have ended
})
})
```
For further information read the linked docs at the top of this readme.
> MIT licensed | **©** [Lossless GmbH](https://lossless.gmbh)
| By using this npm module you agree to our [privacy policy](https://lossless.gmbH/privacy)
[![repo-footer](https://lossless.gitlab.io/publicrelations/repofooter.svg)](https://maintainedby.lossless.com)

38
package-lock.json generated
View File

@ -1,6 +1,6 @@
{ {
"name": "@pushrocks/smartrequest", "name": "@pushrocks/smartrequest",
"version": "1.1.31", "version": "1.1.43",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
@ -407,6 +407,16 @@
"integrity": "sha512-SOhuU4wNBxhhTHxYaiG5NY4HBhDIDnJF60GU+2LqHAdKKer86//e4yg69aENCtQ04n0ovz+tq2YPME5t5yp4pw==", "integrity": "sha512-SOhuU4wNBxhhTHxYaiG5NY4HBhDIDnJF60GU+2LqHAdKKer86//e4yg69aENCtQ04n0ovz+tq2YPME5t5yp4pw==",
"dev": true "dev": true
}, },
"agentkeepalive": {
"version": "4.0.2",
"resolved": "https://verdaccio.lossless.one/agentkeepalive/-/agentkeepalive-4.0.2.tgz",
"integrity": "sha512-A5gSniD4xMCYtSD4ilUHpQRB9ZbNjtIPittKUv7bA0j0UCwbT3EJBUYLKPJ/dtmaXRYWI2mG4/O90xbi7oahNw==",
"requires": {
"debug": "^4.1.0",
"depd": "^1.1.2",
"humanize-ms": "^1.2.1"
}
},
"ansi-256-colors": { "ansi-256-colors": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/ansi-256-colors/-/ansi-256-colors-1.1.0.tgz", "resolved": "https://registry.npmjs.org/ansi-256-colors/-/ansi-256-colors-1.1.0.tgz",
@ -658,6 +668,14 @@
"which": "^1.2.9" "which": "^1.2.9"
} }
}, },
"debug": {
"version": "4.1.1",
"resolved": "https://verdaccio.lossless.one/debug/-/debug-4.1.1.tgz",
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
"requires": {
"ms": "^2.1.1"
}
},
"decamelize": { "decamelize": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
@ -695,6 +713,11 @@
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
}, },
"depd": {
"version": "1.1.2",
"resolved": "https://verdaccio.lossless.one/depd/-/depd-1.1.2.tgz",
"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
},
"diff": { "diff": {
"version": "4.0.1", "version": "4.0.1",
"resolved": "https://verdaccio.lossless.one/diff/-/diff-4.0.1.tgz", "resolved": "https://verdaccio.lossless.one/diff/-/diff-4.0.1.tgz",
@ -844,6 +867,14 @@
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
"dev": true "dev": true
}, },
"humanize-ms": {
"version": "1.2.1",
"resolved": "https://verdaccio.lossless.one/humanize-ms/-/humanize-ms-1.2.1.tgz",
"integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=",
"requires": {
"ms": "^2.0.0"
}
},
"inflight": { "inflight": {
"version": "1.0.6", "version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
@ -1045,6 +1076,11 @@
"moment": ">= 2.9.0" "moment": ">= 2.9.0"
} }
}, },
"ms": {
"version": "2.1.2",
"resolved": "https://verdaccio.lossless.one/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"nice-try": { "nice-try": {
"version": "1.0.5", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",

View File

@ -1,6 +1,6 @@
{ {
"name": "@pushrocks/smartrequest", "name": "@pushrocks/smartrequest",
"version": "1.1.31", "version": "1.1.43",
"private": false, "private": false,
"description": "dropin replacement for request", "description": "dropin replacement for request",
"main": "dist/index.js", "main": "dist/index.js",
@ -25,6 +25,7 @@
"dependencies": { "dependencies": {
"@pushrocks/smartpromise": "^3.0.5", "@pushrocks/smartpromise": "^3.0.5",
"@types/form-data": "^2.5.0", "@types/form-data": "^2.5.0",
"agentkeepalive": "^4.0.2",
"form-data": "^2.5.1" "form-data": "^2.5.1"
}, },
"devDependencies": { "devDependencies": {
@ -37,12 +38,12 @@
"tslint-config-prettier": "^1.18.0" "tslint-config-prettier": "^1.18.0"
}, },
"files": [ "files": [
"ts/*", "ts/**/*",
"ts_web/*", "ts_web/**/*",
"dist/*", "dist/**/*",
"dist_web/*", "dist_web/**/*",
"dist_ts_web/*", "dist_ts_web/**/*",
"assets/*", "assets/**/*",
"cli.js", "cli.js",
"npmextra.json", "npmextra.json",
"readme.md" "readme.md"

View File

@ -21,7 +21,7 @@ tap.test('should request a JSON document over https', async () => {
.equal(1); .equal(1);
}); });
tap.test('should post a JSON document over http', async () => { tap.skip.test('should post a JSON document over http', async () => {
await expect(smartrequest.postJson('http://md5.jsontest.com/?text=example_text')) await expect(smartrequest.postJson('http://md5.jsontest.com/?text=example_text'))
.to.eventually.property('body') .to.eventually.property('body')
.property('md5') .property('md5')

View File

@ -8,16 +8,37 @@ import { request } from './smartrequest.request';
export interface IFormField { export interface IFormField {
name: string; name: string;
type: 'string' | 'filePath' | 'Buffer'; type: 'string' | 'filePath' | 'Buffer';
payload: string; payload: string | Buffer;
fileName?: string;
} }
const appendFormField = async (formDataArg: plugins.formData, formDataField: IFormField) => { const appendFormField = async (formDataArg: plugins.formData, formDataField: IFormField) => {
if (formDataField.type === 'filePath') { switch (formDataField.type) {
let fileData = plugins.fs.readFileSync(plugins.path.join(process.cwd(), formDataField.payload)); case 'string':
formDataArg.append('file', fileData, { formDataArg.append(formDataField.name, formDataField.payload);
filename: 'upload.pdf', break;
contentType: 'application/pdf' case 'filePath':
}); if (typeof formDataField.payload !== 'string') {
throw new Error(
`Payload for key ${
formDataField.name
} must be of type string. Got ${typeof formDataField.payload} instead.`
);
}
const fileData = plugins.fs.readFileSync(
plugins.path.join(process.cwd(), formDataField.payload)
);
formDataArg.append('file', fileData, {
filename: formDataField.fileName ? formDataField.fileName : 'upload.pdf',
contentType: 'application/pdf'
});
break;
case 'Buffer':
formDataArg.append('file', formDataField.payload, {
filename: formDataField.fileName ? formDataField.fileName : 'upload.pdf',
contentType: 'application/pdf'
});
break;
} }
}; };
@ -30,14 +51,15 @@ export const postFormData = async (
for (const formField of payloadArg) { for (const formField of payloadArg) {
await appendFormField(form, formField); await appendFormField(form, formField);
} }
const requestOptions = Object.assign({}, optionsArg, { const requestOptions = {
...optionsArg,
method: 'POST', method: 'POST',
headers: { headers: {
...optionsArg.headers, ...optionsArg.headers,
...form.getHeaders() ...form.getHeaders()
}, },
requestBody: form requestBody: form
}); };
// lets fire the actual request for sending the formdata // lets fire the actual request for sending the formdata
const response = await request(urlArg, requestOptions); const response = await request(urlArg, requestOptions);

View File

@ -8,3 +8,8 @@ import * as url from 'url';
import * as smartpromise from '@pushrocks/smartpromise'; import * as smartpromise from '@pushrocks/smartpromise';
export { formData, http, https, fs, path, url, smartpromise }; export { formData, http, https, fs, path, url, smartpromise };
// third party scope
import * as agentkeepalive from 'agentkeepalive';
export { agentkeepalive };

View File

@ -57,10 +57,7 @@ const parseSocketPathAndRoute = (stringToParseArg: string) => {
/** /**
* a custom http agent to make sure we can set custom keepAlive options for speedy subsequent calls * a custom http agent to make sure we can set custom keepAlive options for speedy subsequent calls
*/ */
const httpAgent = new plugins.http.Agent({ const httpAgent = new plugins.agentkeepalive.default();
keepAlive: true,
keepAliveMsecs: 600000
});
/** /**
* a custom http agent to make sure we can set custom keepAlive options for speedy subsequent calls * a custom http agent to make sure we can set custom keepAlive options for speedy subsequent calls
@ -74,10 +71,7 @@ const httpAgentKeepAliveFalse = new plugins.http.Agent({
/** /**
* a custom https agent to make sure we can set custom keepAlive options for speedy subsequent calls * a custom https agent to make sure we can set custom keepAlive options for speedy subsequent calls
*/ */
const httpsAgent = new plugins.https.Agent({ const httpsAgent = new plugins.agentkeepalive.HttpsAgent();
keepAlive: true,
keepAliveMsecs: 600000
});
/** /**
* a custom https agent to make sure we can set custom keepAlive options for speedy subsequent calls * a custom https agent to make sure we can set custom keepAlive options for speedy subsequent calls
@ -91,7 +85,8 @@ const httpsAgentKeepAliveFalse = new plugins.https.Agent({
export let request = async ( export let request = async (
domainArg: string, domainArg: string,
optionsArg: interfaces.ISmartRequestOptions = {}, optionsArg: interfaces.ISmartRequestOptions = {},
streamArg: boolean = false responseStreamArg: boolean = false,
requestDataFunc: (req: plugins.http.ClientRequest) => void = null
): Promise<IExtendedIncomingMessage> => { ): Promise<IExtendedIncomingMessage> => {
const done = plugins.smartpromise.defer<any>(); const done = plugins.smartpromise.defer<any>();
@ -130,13 +125,13 @@ export let request = async (
case parsedUrl.protocol === 'https:' && optionsArg.keepAlive: case parsedUrl.protocol === 'https:' && optionsArg.keepAlive:
optionsArg.agent = httpsAgent; optionsArg.agent = httpsAgent;
return plugins.https; return plugins.https;
case parsedUrl.protocol === 'https:' && (!optionsArg.keepAlive): case parsedUrl.protocol === 'https:' && !optionsArg.keepAlive:
optionsArg.agent = httpsAgentKeepAliveFalse; optionsArg.agent = httpsAgentKeepAliveFalse;
return plugins.https; return plugins.https;
case parsedUrl.protocol === 'http:' && optionsArg.keepAlive: case parsedUrl.protocol === 'http:' && optionsArg.keepAlive:
optionsArg.agent = httpAgent; optionsArg.agent = httpAgent;
return plugins.http; return plugins.http;
case parsedUrl.protocol === 'http:' && (!optionsArg.keepAlive): case parsedUrl.protocol === 'http:' && !optionsArg.keepAlive:
optionsArg.agent = httpAgentKeepAliveFalse; optionsArg.agent = httpAgentKeepAliveFalse;
return plugins.http; return plugins.http;
} }
@ -144,7 +139,7 @@ export let request = async (
// lets perform the actual request // lets perform the actual request
const requestToFire = requestModule.request(optionsArg, async response => { const requestToFire = requestModule.request(optionsArg, async response => {
if (streamArg) { if (responseStreamArg) {
done.resolve(response); done.resolve(response);
} else { } else {
const builtResponse = await buildUtf8Response(response, optionsArg.autoJsonParse); const builtResponse = await buildUtf8Response(response, optionsArg.autoJsonParse);
@ -165,6 +160,8 @@ export let request = async (
requestToFire.write(optionsArg.requestBody); requestToFire.write(optionsArg.requestBody);
requestToFire.end(); requestToFire.end();
} }
} else if (requestDataFunc) {
requestDataFunc(requestToFire);
} else { } else {
requestToFire.end(); requestToFire.end();
} }